import java.io.*;
import java.text.*;
import java.util.*;
import java.lang.reflect.*;
import java.lang.*;
import javax.json.*;
import gsfc.nssdc.cdf.*;
import gsfc.nssdc.cdf.util.*;

/**
 * The Json2CDF class is the converter to convert a Json file back to a CDF.
 * The Json file is produced from CDF2Json class. The Json file has the
 * following form:
 *<PRE>
 *CDFname1:
 *  CDFFileInfo:
 *    FileVersion:.....
 *    Format:.....
 *    Majority:...
 *    Encoding:.....
 *    Checksum:.....
 *  CDFglobalAttributes:
 *    Gattr_name1:
 *     entry#:value
 *       ...
 *       ...
 *    Gattr_name2:
 *     entry#:value
 *       ...
 *       ...
 *    ...
 *    ...
 *  CDFVariables:
 *    VarName1:
 *     VarDescription:
 *       DataType:....
 *       ...
 *       ...
 *     VarAttributes:
 *       VALIDMIN:.... or VALIDMIN: DataType:... Value:...
 *       VALIDMAX:.... or VALIDMAX: DataType:... Value:...
 *       ...
 *       ...
 *     VarData:
 *       ...
 *    VarName2:
 *     VarDescription:
 *       DataType:....
 *       ...
 *       ...
 *     VarAttributes:
 *       VALIDMIN:....
 *       VALIDMAX:....
 *       ...
 *       ...
 *     VarData:
 *       ...
 *  EmptyAttributes:        <== If attribute(s) defined but not assign value(s)
 *     GlobalAttributes:    <== If global attribute(s) is not assigned value
 *     VariableAttributes:  <== If variable attribute(s) is not assigned value
 *
 *CDFname2:
 *  CDFFileInfo:
 *   .....
 *   .....
 *  CDFglobalAttributes:
 *    Gattr_name1:
 *       ...
 *       ...
 *    Gattr_name2:
 *       ...
 *       ...
 *    ...
 *    ...
 *  CDFVariables:
 *    VarName1:
 *     VarDescription:
 *       ....
 *...
 *...
 *</PRE> 
 *
 * 
 * This class is based on JNI-based cdfjava.jar and javax.json.jar.
 *
 * @version 2.0 02/20/2022  
 * @author Mike Liu,      ADNET Systems
 */

public class Json2CDF implements CDFConstants {

   private static boolean progress = false,
                          delete = false,
                          showfile = false,
                          toCompress = true,
                          checksum = false;
   private static String inFile = null,
                         assignedFile = null,
                         outDir = null;
   private static int numFiles = 0;
   private static long dataType, numElements;
   private static boolean varData = true;
   private static long varDataType, varNumElems, varNumDims, varRecItems;
   private static long varSparseRec = NO_SPARSERECORDS;
   private static long varNumWritten = 0, varMaxWritten = -1;
   private static long[] varDimSizes = new long[(int)CDF_MAX_DIMS];
   private static long[] varDimVariances = new long[(int)CDF_MAX_DIMS];
   private static String varName = null;
   private static Object varPadValue = null;
   private static Object varFillVal = null;
   private static long varRecVary = VARY;
   private static String separator = System.getProperty("file.separator");
   private static String item1 = "CDFFileInfo";
   private static String item2 = "CDFglobalAttributes";
   private static String item3 = "CDFVariables";
   private static String item4 = "VarDescription";
   private static String item5 = "VarAttributes";
   private static String item6 = "VarData";
   private static String item7 = "EmptyAttributes";
   private static String vAttrName = null;
   private static long dataTypeY = -1;
   private static long compression = -1, compLvl = 0;

   private static CDF cdf = null;
   private static Variable var = null;
   private static int index = 0;

   public static void main(String[] args) throws IOException {
     try {
       parseCmdLine(args);
       if (showfile) System.out.println(inFile);
       InputStream fis = new FileInputStream(inFile);
       JsonReader jsonReader = Json.createReader(fis);
       JsonObject jsonObject = jsonReader.readObject();
       jsonReader.close();
       fis.close();

       numFiles = jsonObject.keySet().size();

       for (String cdfName: jsonObject.keySet()) {
           outPutJsonObject(cdfName, 
                            (JsonObject)jsonObject.getJsonObject(cdfName));
       }

     } catch (Exception ep) {
       System.out.println("Exception... "+ep);
     }
   }

   private static void outPutJsonObject (String cdfName, 
                                         JsonObject jsonObject1) {
     long format = -1, majority = -1, encoding = -1, checksumi = 0;
     cdf = null;
     String createdCDF = null;

     try {
       if (progress) System.out.println("Doing CDFFileInfo...");
       JsonArray fileInfoArray = jsonObject1.getJsonArray(item1);
       if (fileInfoArray != null) {
         if (progress) System.out.println(item1+":");
         for (JsonValue fileInfo : fileInfoArray) {
           for (String key: ((JsonObject)fileInfo).keySet()) {
             String value = ((JsonObject)fileInfo).getString(key);
             if (progress) System.out.println("  "+key+":"+value);
             if (key.equalsIgnoreCase("filename")) {
               cdfName = value;
             } else if (key.equalsIgnoreCase("format")) {
               format = CDFUtils.getLongFormat (value);
             } else if (key.equalsIgnoreCase("majority")) {
               majority = CDFUtils.getLongMajority (value);
             } else if (key.equalsIgnoreCase("encoding")) {
               encoding = CDFUtils.getLongEncoding (value);
             } else if (key.equalsIgnoreCase("checksum")) {
               checksumi = CDFUtils.getLongChecksum (value);
             } 
           }
         }
         String toDelete = null;
         if (delete) {
           File cdfFile;
           if (outDir == null) {
              if (numFiles == 1 && assignedFile != null)
                  toDelete = assignedFile;
                else
                  toDelete = cdfName;
           } else {
               int loc;
               if (numFiles == 1 && assignedFile != null)
                 toDelete = outDir + separator + assignedFile;
               else {
                 loc = cdfName.lastIndexOf(separator);
                 if (loc != -1)
                   toDelete = outDir + separator + cdfName.substring(loc+1);
                 else
                   toDelete = outDir + separator + cdfName;
               }
           }
           cdfFile = new File(toDelete);
           if (cdfFile.exists()) cdfFile.delete();
         }

         if (outDir == null)
             if (numFiles == 1 && assignedFile != null)
               createdCDF = assignedFile;
             else
               createdCDF = cdfName;
         else {
             if (numFiles == 1 && assignedFile != null)
               createdCDF = outDir+separator+assignedFile;
             else {
               int loc = cdfName.lastIndexOf(separator);
               if (loc != -1)
                 createdCDF = outDir+separator+cdfName.substring(loc+1);
               else
                 createdCDF = outDir+separator+cdfName;
             }
         }
         cdf = CDF.create(createdCDF);
         cdf.setFormat(format);
         cdf.setMajority(majority);
         cdf.setEncoding(encoding);
         if (checksum || checksumi == MD5_CHECKSUM)
           cdf.setChecksum(MD5_CHECKSUM);
       }
       
       // Retrieve data from "CDFglobalAttributes" JsonArray
       if (progress) System.out.println("Doing CDFglobalAttributes...");
       JsonArray globalAttrArray = jsonObject1.getJsonArray(item2);
       if (globalAttrArray != null) {
         if (progress) System.out.println(item2+":");
         processGlobalAttributes (globalAttrArray);
       }

       // Retrieve data from "CDFVariables" JsonArray
       if (progress) System.out.println("Doing CDFVariables...");
       JsonArray cdfVariables = jsonObject1.getJsonArray(item3);
       if (cdfVariables != null) {
         if (progress) System.out.println(item3+":");
         for (JsonValue varInfo : cdfVariables) {
           for (String varName: ((JsonObject)varInfo).keySet()) {
             if (progress) System.out.println("  "+varName+":");
             JsonArray varItems = ((JsonObject)varInfo).getJsonArray(varName);
             for (int ii = 0; ii < varItems.size(); ++ii) {
               JsonObject varItem = varItems.getJsonObject(ii);
               for (String itemName: varItem.keySet()) {
                 if (itemName.equalsIgnoreCase(item4)) {
                   Object values = varItem.get(itemName);
                   // VarDescription
                   if (progress) System.out.println("    "+itemName+":");
                   var = processVariableSpec (varName, values);
                   index = 0;
                 } else if (itemName.equalsIgnoreCase(item5)) {
                   if (var != null) {
                     Object values = varItem.get(itemName);
                     // VarAttributes
                     if (progress) System.out.println("    "+itemName+":");
                     processVariableAttributes (values);
                   }
                 } else if (itemName.equalsIgnoreCase(item6)) {
                   if (varData || (varRecVary == NOVARY)) {
                     if (var != null) {
                       // VarData
                       if (progress) System.out.println("    Doing VarData....");
                       Object varDatax = varItem.get(itemName);
                       if (varDatax != null)
                         processVariableData (varDatax);
                     }
                   }
                 } else
                   System.out.println("***** Unknown item...: "+itemName);
               }
             }
           }
         }
       }

       if (progress) System.out.println("Doing EmptyAttributes...");
       JsonArray emptyAttrs = jsonObject1.getJsonArray(item7);
       if (emptyAttrs != null) {
         if (progress) System.out.println(item7+":");
         for (JsonValue groupAttrs : emptyAttrs) {
           for (String key: ((JsonObject)groupAttrs).keySet()) {
             JsonArray values = ((JsonObject)groupAttrs).getJsonArray(key);
             if (progress) System.out.println("  "+key+":"+values);
             if (key.equals("GlobalAttributes")) {
               for (int ii=0; ii < values.size(); ++ii) {
                 String attrName = values.getString(ii);
                 Attribute.create(cdf, attrName, GLOBAL_SCOPE);
               }
             } else {
               for (int ii=0; ii < values.size(); ++ii) {
                 String attrName = values.getString(ii);
                 Attribute.create(cdf, attrName, VARIABLE_SCOPE);
               }
             }
           }
         }
       }
       cdf.close();
     } catch (Exception ex) {
       System.err.println("***** Error: "+ex+" for file: "+createdCDF);
       StackTraceElement[] stackTrace = ex.getStackTrace();
       if (stackTrace.length > 0) {
         int lineNumber = stackTrace[0].getLineNumber();
         System.out.println("Exception occurred at line number: " + lineNumber);
       } else {
         System.out.println("Could not determine the line number of the exception.");
       }
     }
   }

   /*********************************************************/
   /*  Parse the command line input that is in the form of  */
   /*     java Json2CDF [Options] cdfFileName              */
   /*                                                       */
   /*  See the top of this file for a detailed description  */
   /*  of the Options.                                      */
   /*********************************************************/
   private static void parseCmdLine (String[] args) {
       String numSpaces = null;

       if (args.length == 0) {      // No input is given (i.e. java Json2CDF)
           usage();
           exit("");
       } else {                  // Process options
         for (int i=0; i < args.length; i++) {
            if (i == (args.length-1)) {         // Get the CDF file name
                inFile = args[i];
            }
            else {
                int loc = args[i].indexOf(":");
                if (args[i].toLowerCase().startsWith("-output:")) {
                    assignedFile = args[i].substring(loc+1);
                    if (!assignedFile.toLowerCase().endsWith(".cdf"))
                      assignedFile = assignedFile + ".cdf";
                }
                else if (args[i].toLowerCase().startsWith("-vardata:")) {
                    String toData = args[i].substring(loc+1);
                    if (toData.equalsIgnoreCase("yes")) 
                      varData = true;
                    else if (toData.equalsIgnoreCase("no"))
                      varData = false;
                    else {
                      exit("** Error: Invalid option \"-vardata:"+toData+
                           "\" entered.\n");
                    }
                }
                else if (args[i].equalsIgnoreCase("-showprogress") ||
                         args[i].equalsIgnoreCase("-progress")) {
                    progress = true;
                }
                else if (args[i].equalsIgnoreCase("-delete")) {
                    delete = true;
                }
                else if (args[i].equalsIgnoreCase("-showfile")) {
                    showfile = true;
                }
                else if (args[i].equalsIgnoreCase("-checksum")) {
                    checksum = true;
                }
                else if (args[i].equalsIgnoreCase("-nocompress")) {
                    toCompress = false;
                }
                else if (args[i].toLowerCase().startsWith("-outdir:")) {
                    outDir = args[i].substring(loc+1);
                }
                else {
                    System.out.println ("** Error: Invalid/missing option"+
                          " entered for \""+args[i]+"\"\n"+
                          "   Use \"java CDF2Json\" to read the help information.");
                    System.exit(1);
                }
            }
         }
       }
   }

   private static boolean equivalentDataTypes (long dataType1, long dataType2) {
       long realDataType[] = {
          0,1,2,0,3,0,0,0,4,0,
          0,5,6,0,7,0,0,0,0,0,
          0,8,9,0,0,0,0,0,0,0,
          0,9,0,4,0,0,0,0,0,0,
          0,1,0,0,8,9,0,0,0,0,
          0,10,10,0,0,0,0,0,0,0
       };
       return (realDataType[(int)dataType1] == realDataType[(int)dataType2]);
   }

   private static Object handleSpecial (long dt, String str) {

       if (str.equals("-nan")) {
           if (dt == CDF_DOUBLE || dt == CDF_REAL8)
             return Double.valueOf(-Double.NaN);
           if (dt == CDF_FLOAT || dt == CDF_REAL4)
             return Float.valueOf(-Float.NaN);
           return Double.valueOf(-Double.NaN);
       } else if (str.equals("nan")) {
           if (dt == CDF_DOUBLE || dt == CDF_REAL8)
             return Double.valueOf(Double.NaN);
           if (dt == CDF_FLOAT || dt == CDF_REAL4)
             return Float.valueOf(Float.NaN);
           return Double.valueOf(Double.NaN);
       } else if (str.equals("-inf")) {
           if (dt == CDF_DOUBLE || dt == CDF_REAL8)
             return Double.valueOf(Double.NEGATIVE_INFINITY);
           if (dt == CDF_FLOAT || dt == CDF_REAL4)
             return Float.valueOf(Float.NEGATIVE_INFINITY);
           return Double.valueOf(Double.NEGATIVE_INFINITY);
       } else if (str.equals("inf")) {
           if (dt == CDF_DOUBLE || dt == CDF_REAL8)
             return Double.valueOf(Double.POSITIVE_INFINITY);
           if (dt == CDF_FLOAT || dt == CDF_REAL4)
             return Float.valueOf(Float.POSITIVE_INFINITY);
           return Double.valueOf(Double.POSITIVE_INFINITY);
       }
       if (dt == CDF_INT8) {
         return Long.valueOf(str);
       } else if (dt == CDF_DOUBLE) {
         return Double.valueOf(str);
       }
       return str;
   }

   private static Object changeData (long dt1, long dt2, Object data) {

       String signature = CDFUtils.getSignature(data);
       if (signature.indexOf("String") != -1) {
         if (signature.charAt(0) != '[') {
           String str = (String) data;
           String str2 = specialString(str);
           if (str2 != null)
             return handleSpecial (dt2, str2);
           else
             return data;
         } else {
           int items = ((String[])data).length;
           String str = null, str2 = null;
           if (dt2 == CDF_REAL4 || dt2 == CDF_FLOAT) {
             float[] nd = new float[items];
             for (int i = 0; i < items; ++i) {
               str = ((String[]) data)[i];
               str2 = specialString(str);
               if (str2 != null)
                 nd[i] = ((Float) handleSpecial (dt2, str2));
               else
                 nd[i] = Float.valueOf(str);
             }
             return nd;
           } else if (dt2 == CDF_REAL8 || dt2 == CDF_DOUBLE) {
             double[] nd = new double[items];
             for (int i = 0; i < items; ++i) {
               str = ((String[]) data)[i];
               str2 = specialString(str);
               if (str2 != null)
                 nd[i] = ((Double) handleSpecial (dt2, str2));
               else
                 nd[i] = Double.valueOf(str);
             }
             return nd;
           } else
             return data;
         }
       }
       if (equivalentDataTypes(dt1, dt2)) return data;
       if (data instanceof Double) {
         return Float.valueOf((float)((Double)data).doubleValue());
       } else if (data instanceof Integer) {
         if (dt1 == CDF_INT1 || dt1 == CDF_BYTE)
           return Byte.valueOf((byte)((Integer)data).byteValue());
         else if (dt1 == CDF_INT2 || dt1 == CDF_UINT1)
           return Short.valueOf((short)((Integer)data).shortValue());
       } else {
         if (signature.charAt(0) == '[') {
           if (signature.charAt(1) == 'D') {
             int items = ((double[])data).length;
             float[] nd = new float[items];
             for (int i = 0; i < items; ++i)
               nd[i] = (float) ((double[])data)[i];
             return nd;
           } else {
             if (dt1 == CDF_INT1 || dt1 == CDF_BYTE) {
               int items = ((int[])data).length;
               byte[] nd = new byte[items];
               for (int i = 0; i < items; ++i) 
                 nd[i] = (byte) ((int[])data)[i];
               return nd;
             } else if (dt1 == CDF_INT2 || dt1 == CDF_UINT1) {
               int items = ((int[])data).length;
               short[] nd = new short[items];
               for (int i = 0; i < items; ++i)
                 nd[i] = (short) ((int[])data)[i];
               return nd;
             } else 
               return data;
           }
         }
       }
       return data; 
   }

   private static Object getData (Object data, long dataTypei) {

       String value = null;
       if (data instanceof JsonString) {
         value = ((JsonString)data).toString();
         int len = value.length();
         if (len == 0) return new String(new byte[] {0});
         if (value.charAt(0) == '"') {
           value = value.substring(1, value.length()-1);
           len = value.length();
           if (len == 0) return new String(new byte[] {0});
         }
         if (dataTypei != 0) {
           dataType = dataTypei;
           Object val = parseContents (value, dataType);
           if (val != null) return val;
           else return value;
         } else {
           try {
             if (len < 14 || value.charAt(4) != '-' || value.charAt(7) != '-' ||
               value.charAt(10) != 'T' || value.charAt(13) != ':') {
               dataType = CDF_CHAR;
               Object val =  parseContents (value, dataType);
               if (val != null) return val;
               else return value;
             } else {
               numElements = 1;
               if (value.length() == 23 || value.length() == 24) { // EPOCH
                   dataType = CDF_EPOCH;
                   return Double.valueOf(Epoch.toParse(value));
               } else if (value.length() == 29 ||
                          value.length() == 30) { // TT2000
                   dataType = CDF_TIME_TT2000;
                   return Long.valueOf(CDFTT2000.toParse(value));
               } else if (value.length() == 32 ||
                          value.length() == 36) { // EPOCH16
                   dataType = CDF_EPOCH16;
                   double[] epoch16 = Epoch16.toParse(value);
                   return epoch16;
               } else {
                   dataType = CDF_CHAR;
                   return value;
               }
             }
           } catch (Exception ee) {
             numElements = len;
             dataType = CDF_CHAR;
             return value;
           }
         }
       } else if (data instanceof JsonNumber) {
         numElements = 1;
         try {
           value = ((JsonNumber)data).toString();
           if (dataTypei == 0) {
             if (((JsonNumber)data).isIntegral()) {
               if (!useVarDataType(vAttrName))
                 dataType = CDF_INT4;
               try {
                 Object val = parseContents (value, dataType);
                 if (val != null) return val;
                 else return value;
               } catch (Exception ei4) {
                 try {
                   dataType = CDF_INT8;
                   Object val = parseContents (value, dataType);
                   if (val != null) return val;
                   else return value;
                 } catch (Exception ei8) {
                   System.out.println("1 Error.... Json number... value:"+value+
                                      " dt:"+dataType+" "+ei8);
                   return null;
                 }
               }
             } else {
               if (!useVarDataType(vAttrName))
                   dataType = CDF_DOUBLE;
             }
           } else
               dataType = dataTypei;
           Object val = parseContents (value, dataType);
           if (val != null) return val;
           else return value;
         } catch (Exception ee) {
           System.out.println("2 Error.... Json number... value:"+value+" dt:"+
                              dataType+" "+ee);
           return null;
         }
       } else if (data instanceof JsonArray) {
         Object one = ((JsonArray)data).get(0);
         if (one instanceof JsonNumber) {
           numElements = ((JsonArray)data).size();
           StringBuffer sb = new StringBuffer();
           for (int ii=0; ii<numElements; ++ii) {
             sb.append(((JsonNumber)((JsonArray)data).get(ii)).toString());
             if (ii < (numElements - 1)) sb.append(",");
           }
           value = sb.toString();
           if (dataTypei == 0) {
             if (((JsonNumber)one).isIntegral()) {
               if (!useVarDataType(vAttrName))
                 dataType = CDF_INT4;
               try {
                 Object val = parseContents (value, dataType);
                 if (val != null) return val;
                 else return value;
               } catch (Exception ei4) {
                 try {
                   dataType = CDF_INT8;
                   Object val = parseContents (value, dataType);
                   if (val != null) return val;
                   else return value;
                 } catch (Exception ei8) {
                   System.out.println("3 Error.... Json array integer... value:"
                                      +value+" dt:"+dataType+" "+ei8);
                   return null;
                 }
               }
             } else {
               if (!useVarDataType(vAttrName))
                 dataType = CDF_DOUBLE;
             }
           } else dataType = dataTypei;
           try {
             Object val = parseContents (value, dataType);
             if (val != null) return val;
             else return value;
           } catch (Exception ee) {
             System.out.println("4 Error.... Json array number... value:"+
                                value+" dt:"+dataType+" "+ee);
             return null;    
           }
         } else if (one instanceof JsonString) {
           if (dataTypei == CDF_CHAR || dataTypei == CDF_UCHAR ||
               dataTypei == 0) {
             Object onex = parseContents (((JsonString)one).toString(),
                                           CDF_CHAR);
             if (onex instanceof String) {
               int sItems = ((JsonArray)data).size();
               String[] tmpStrings = new String[sItems];
               for (int ii = 0; ii < sItems; ++ii) {
                 tmpStrings[ii] = 
                     (String) getData((JsonString)(((JsonArray)data).get(ii)),
                                      CDF_CHAR);
               }
               return tmpStrings;
             } else {
               Object val = parseContents (value, dataType);
               if (val != null) return val;
               else return value;
             }
           } else {
             int nItems = ((JsonArray)data).size();
             if (dataTypei == CDF_INT8 || dataTypei == CDF_TIME_TT2000) {
               long[] outs = new long[nItems]; 
               for (int jj = 0; jj < nItems; ++jj) {
                 String aValue1 = ((JsonString) ((JsonArray)data).get(jj)).getString();
                 String aValue2 = (String) parseContents (aValue1, CDF_CHAR);
                 outs[jj] = Long.valueOf(aValue2);
               }
               return outs;
             } else if (dataTypei == CDF_DOUBLE || dataTypei == CDF_REAL8) {
               double[] outs = new double[nItems];
               for (int jj = 0; jj < nItems; ++jj) {
                 String aValue1 = ((JsonString) ((JsonArray)data).get(jj)).getString();
                 String aValue2 = (String) parseContents (aValue1, CDF_CHAR);
                 outs[jj] = Double.valueOf(aValue2);
               }
               return outs;
             } else
               return null;
           }
         } else
           return null;
       }
       return null;
   }

   private static String specialString (String string) {
       String str = string.toLowerCase();
       if (str.startsWith("\""))
         str = str.substring(1, str.length()-1);
       if (str.equals("nan") || str.equals("-nan") ||
           str.equals("inf") || str.equals("-inf"))
         return str;
       else
         return null; 
   }

   /*****************************************************************/
   /*  Move data in a JsonArray into the buffer array.
   /*****************************************************************/
   private static Object setData (Object valuesi, Object buf) throws CDFException {

       Object values;
       values = valuesi;
       int nItems, items = 1;
       Object data;
       nItems = ((JsonArray)values).size();

       for (int jj = 0; jj < nItems; ++jj) {
           data = (Object) ((JsonArray)values).get(jj);
         String signature =   CDFUtils.getSignature(data);
         Object newObj = null;
         if (data instanceof JsonString) {
           String str = ((JsonString)data).getString();
           String str2 = specialString(str);
           if (str2 != null) {
             newObj = handleSpecial (varDataType, str2);
           } else
             newObj = setData1 (data);
           switch ((int)varDataType) {
               case (int)CDF_EPOCH:
                 ((double[])buf)[index++] = ((Double)newObj).doubleValue();
                 break;
               case (int)CDF_INT8:
               case (int)CDF_TIME_TT2000:
                 ((long[])buf)[index++] = ((Long)newObj).longValue();
                 break;
               case (int) CDF_EPOCH16:
                 ((double[])buf)[index++] = ((double[])newObj)[0];
                 ((double[])buf)[index++] = ((double[])newObj)[1];
                 break;
               case (int) CDF_CHAR:
               case (int) CDF_UCHAR:
                 byte[] by = ((String)newObj).getBytes();
                 int len = ((String)newObj).length();
                 for (int xy = 0; xy < len; ++xy)
                   ((byte[])buf)[index+xy] = by[xy];
                 for (int xy = len; xy < varNumElems; ++xy)
                   ((byte[])buf)[index+xy] = (byte) 0;
                 index += varNumElems;
                 break;
               default:
                 break;
           }
         } else if (data instanceof JsonNumber) {
           newObj = setData1 (data);
           switch ((int)varDataType) {
             case (int)CDF_BYTE:
             case (int)CDF_INT1:
               ((byte[])buf)[index++] = (byte) ((Byte)newObj).byteValue();
               break;
             case (int)CDF_INT2:
             case (int)CDF_UINT1:
               ((short[])buf)[index++] = (short)((JsonNumber)data).intValue();
               break;
             case (int)CDF_INT4:
             case (int)CDF_UINT2:
               ((int[])buf)[index++] = ((JsonNumber)data).intValue();
               break;
             case (int)CDF_UINT4:
             case (int)CDF_INT8:
             case (int)CDF_TIME_TT2000:
               ((long[])buf)[index++] = ((JsonNumber)data).longValue();
               break;
             case (int)CDF_REAL4:
             case (int)CDF_FLOAT:
               ((float[])buf)[index++] = (float)(((JsonNumber)data).doubleValue());
               break;
             case (int)CDF_REAL8:
             case (int)CDF_DOUBLE:
             case (int)CDF_EPOCH:
             case (int)CDF_EPOCH16:
               ((double[])buf)[index++] = ((JsonNumber)data).doubleValue();
               break;
             default:
               break;
           }
         } else if (data instanceof JsonArray) {
           buf = setData (data, buf);
         } else {
           System.out.println("                     ?????");
           return null;
         }
       }
       return buf; 
   }

   /*****************************************************************/
   /*  Returns an object from a single JsonObject.
   /*****************************************************************/
   private static Object setData1 (Object data) throws CDFException {

       String value;
       if (data instanceof JsonString || data instanceof String) {
         if (data instanceof JsonString)
           value = ((JsonString)data).toString();
         else
           value = (String) data;
         if (value.charAt(0) == '"')
           value = value.substring(1, value.length()-1);
         switch ((int)varDataType) {
           case (int)CDF_EPOCH:
             if (value.indexOf("-") != -1 && value.indexOf(":") != -1)
               return Double.valueOf(Epoch.toParse(value));
             else
               return Double.valueOf(value);
           case (int)CDF_TIME_TT2000:
             if (value.indexOf("-") != -1 && value.indexOf(":") != -1)
               return Long.valueOf(CDFTT2000.toParse(value));
             else
               return Long.valueOf(value);
           case (int)CDF_EPOCH16:
             if (value.indexOf("-") != -1 && value.indexOf(":") != -1)
               return Epoch16.toParse(value);
             else {
               System.out.println("????? value"+value+" NOT handled for EPOCH16...");
               return null;
             }
           case (int) CDF_INT8:
             return Long.valueOf(value);
           default:
             return value;
         }
       } else if (data instanceof JsonNumber) {
         switch ((int)varDataType) {
           case (int)CDF_BYTE:
           case (int)CDF_INT1:
             return Byte.valueOf((byte)((JsonNumber)data).intValue());
           case (int)CDF_INT2:
           case (int)CDF_UINT1:
             return Short.valueOf((short)((JsonNumber)data).intValue());
           case (int)CDF_INT4:
           case (int)CDF_UINT2:
             return Integer.valueOf(((JsonNumber)data).intValue());
           case (int)CDF_UINT4:
           case (int)CDF_INT8:
           case (int)CDF_TIME_TT2000:
             return Long.valueOf(((JsonNumber)data).longValue());
           case (int)CDF_REAL4:
           case (int)CDF_FLOAT:
             return Float.valueOf((float)((JsonNumber)data).doubleValue());
           case (int)CDF_REAL8:
           case (int)CDF_DOUBLE:
           case (int)CDF_EPOCH:
             return Double.valueOf(((JsonNumber)data).doubleValue());
           default:
             return null;
         }
       } else if (data instanceof JsonArray) {
         switch ((int)varDataType) {
           case (int)CDF_EPOCH16:
             double[] epoch16 = new double[2];
             for (int i = 0; i < 2; ++ i) {
               JsonNumber aVal = (JsonNumber)((JsonArray)data).get(i);
               epoch16[i] = Double.valueOf(aVal.doubleValue());
             }
             return epoch16;
           default:
             return null;
         }
       }
       return null; 
   }

   private static void assignOne (Object outTo, Object inFrom) {
       switch ((int)varDataType) {
         case (int)CDF_BYTE:
         case (int)CDF_INT1:
           ((byte[])outTo)[index++] = ((Byte)inFrom).byteValue();
           break;
         case (int)CDF_INT2:
         case (int)CDF_UINT1:
           ((short[])outTo)[index++] = ((Short)inFrom).shortValue();
           break;
         case (int)CDF_INT4:
         case (int)CDF_UINT2:
           ((int[])outTo)[index++] = ((Integer)inFrom).intValue();
           break;
         case (int)CDF_UINT4:
         case (int)CDF_INT8:
           ((long[])outTo)[index++] = ((Long)inFrom).longValue();
           break;
         case (int)CDF_REAL4:
         case (int)CDF_FLOAT:
           ((float[])outTo)[index++] = ((Float)inFrom);
           break;
         case (int)CDF_REAL8:
         case (int)CDF_DOUBLE:
           ((double[])outTo)[index++] = ((Double)inFrom);
           break;
           default:
         break;
       } // switch

   }

   private static void moveOneRecord (Object outTo, int oStart, Object inFrom,
                                      int iStart, int nItems, long numElems) {
       int i, j, k;
       if (varDataType == CDF_EPOCH16) j = 2;
       else j = 1;
       if (varDataType == CDF_CHAR || varDataType == CDF_UCHAR)
         k = (int)numElems;
       else
         k = 1;
       for (i = 0; i < nItems*j*k; ++i) {
         switch ((int)varDataType) {
           case (int)CDF_BYTE:
           case (int)CDF_INT1:
             ((byte[])outTo)[i+oStart] = ((byte[])inFrom)[i+iStart];
             break;
           case (int)CDF_INT2:
           case (int)CDF_UINT1:
             ((short[])outTo)[i+oStart] = ((short[])inFrom)[i+iStart];
             break;
           case (int)CDF_INT4:
           case (int)CDF_UINT2:
             ((int[])outTo)[i+oStart] = ((int[])inFrom)[i+iStart];
             break;
           case (int)CDF_UINT4:
           case (int)CDF_INT8:
           case (int)CDF_TIME_TT2000:
             ((long[])outTo)[i+oStart] = ((long[])inFrom)[i+iStart];
             break;
           case (int)CDF_REAL4:
           case (int)CDF_FLOAT:
             ((float[])outTo)[i+oStart] = ((float[])inFrom)[i+iStart];
             break;
           case (int)CDF_REAL8:
           case (int)CDF_DOUBLE:
           case (int)CDF_EPOCH:
             ((double[])outTo)[i+oStart] = ((double[])inFrom)[i+iStart];
             break;
           case (int)CDF_EPOCH16:
             ((double[])outTo)[i+oStart] = ((double[])inFrom)[i+iStart];
             break;
           case (int)CDF_CHAR:
           case (int)CDF_UCHAR:
             ((double[])outTo)[i+oStart] = ((double[])inFrom)[i+iStart];
             break;
           default:
             break;
         } // switch
       }

   }

   private static void exit (String msg) {
       if (!msg.equals("")) System.out.println (msg);
       System.exit(1);
   }

   /************************************************************************* 
    *  Print the proper syntax for invoking this program. 
    ************************************************************************/
   private static void usage() {
       System.out.println ("\nDescription:");
       System.out.println ("    This program exports the contents of a Json "+
                           "file into a CDF file(s).");
       System.out.println ("");
       System.out.println ("Usage: java Json2CDF [Options] JsonFileName ");
       System.out.println ("    JsonFileName: The name of the Json file used "+
                           "to create a CDF(s).");
       System.out.println (" ");
       System.out.println ("Options: ");
       System.out.println (" ");
       System.out.println ("   -output:outputFileName");
       System.out.println ("      Use this option to specify a different "+
                           "output file name for the CDF.");
       System.out.println ("      It is only applicable to a single CDF file "+
                           "output.");
       System.out.println (" ");
       System.out.println ("   -outdir:outputDir");
       System.out.println ("      Specifies a directory to hold the output "+
                           "CDF file(s). Make sure the");
       System.out.println ("      directory exists and is writeable.");
       System.out.println (" ");
       System.out.println ("   -vardata:[yes | no].   -vardata:yes is the "+
                           "default.");
       System.out.println ("      Whether to extract var data in the Json "+
                           "file if it is there. If \"no\"");
       System.out.println ("      is specified, non-record varying variables' "+
                           "data will not be extracted.");
       System.out.println (" ");
       System.out.println ("   -[showProgress | Progress]");
       System.out.println ("      This option displays the processing "+
                           "progress on the screen.");
       System.out.println ("      It shows how many CDF variables are there "+
                           "to process and which");
       System.out.println ("      variable is being processed.");
       System.out.println (" ");
       System.out.println ("   -checksum");
       System.out.println ("      This option adds checksum to the file.");
       System.out.println (" ");
       System.out.println ("   -nocompress");
       System.out.println ("      This option forces no compression for "+
                           "variable data. By default, a");
       System.out.println ("      variable with large enough size (>1K) will "+
                           "be compressed, no matter if");
       System.out.println ("      defined by its specification or not.");
       System.out.println (" ");
       System.out.println ("   -delete");
       System.out.println ("      Over-ride the CDF file(s) if it already"+
                           "exists.");
       System.out.println ("");
       System.out.println ("   -showfile");
       System.out.println ("      Display the Json file being processed.");
       System.out.println ("");
       System.out.println ("NOTE:");
       System.out.println ("  1. If an attribute value's data type is not "+
                           "specified, then its");
       System.out.println ("     integral value is converted into 4-byte"+
                           " integer, if it can fill. ");
       System.out.println ("     Otherwise, 8-byte long is used. All floating"+
                           "-values are converted into ");
       System.out.println ("     8-byte doubles.");
       System.out.println ("  2. A varying dimension with size of 1 is "+
                           "considered as non-varying.");
       System.out.println ("     Its dimension is removed and NOT shown.");
       System.out.println ("  3. Values for variable attributes: VALIDMIN/"+
                           "VALIDMAX/SCALEMIN/SCALEMAX/FILLVAL");
       System.out.println ("     will have the same data type as the variable's.");
       System.out.println ("  4. All variables are zVariables.");
       System.out.println ("  5. All \"NaN\"|\"-NaN\" and \"INF\"|\"-INF\" "+
                           "strings are converted into");
       System.out.println ("     floating-point values. ");
       System.out.println ("");
       System.out.println ("Examples: ");

       System.out.println ("   java Json2CDF test.json (same as "+
                           "java Json2CDF -output:test.cdf test.json)");
       System.out.println ("");
       System.out.println ("The Json file should have the following form: "+
                           "(made from CDF2Json):\n\n"+
                           "CDFname1: \n"+
                           " CDFFileInfo: \n"+
                           "   FileVersion:..... \n"+
                           "   Format:..... \n"+
                           "   Majority:... \n"+
                           "   Encoding:..... \n"+
                           "   Checksum:..... \n"+
                           " CDFglobalAttributes: \n"+
                           "   Gattr_name1: \n"+
                           "    entry#:value \n"+
                           "      ... \n"+
                           "   Gattr_name2: \n"+
                           "    entry#:value \n"+
                           "      ... \n"+
                           "   ... \n"+
                           "   ... \n"+
                           " CDFVariables: \n"+
                           "   VarName1: \n"+
                           "    VarDescription: \n"+
                           "      DataType:.... \n"+
                           "      ... \n"+
                           "      ... \n"+
                           "    VarAttributes: \n"+
                           "      VALIDMIN:.... or VALIDMIN:... DataType:... Value:...\n"+
                           "      VALIDMAX:.... or VALIDMAX:... DataType:... Value:...\n"+
                           "      ... \n"+
                           "      ... \n"+
                           "    VarData: \n"+
                           "      ... \n"+
                           "   VarName2: \n"+
                           "    VarDescription: \n"+
                           "      DataType:.... \n"+
                           "      ... \n"+
                           "      ... \n"+
                           "    VarAttributes: \n"+
                           "      ... \n"+
                           "      ... \n"+
                           "    VarData: \n"+
                           "      ... \n"+
                           " EmptyAttributes:   <== If attribute(s) defined but not assign value(s) \n"+
                           "    GlobalAttributes:    <== If global attribute(s) is not assigned value \n"+
                           "    VariableAttributes:  <== If variable attribute(s) is not assigned value \n"+
                           "  \n"+
                           "CDFname2: \n"+
                           " CDFFileInfo: \n"+
                           "  ..... \n"+
                           "  ..... \n"+
                           " CDFglobalAttributes: \n"+
                           "   Gattr_name1: \n"+
                           "      ... \n"+
                           "   Gattr_name2: \n"+
                           "      ... \n"+
                           "   ... \n"+
                           "   ... \n"+
                           " CDFVariables: \n"+
                           "   VarName1: \n"+
                           "    VarDescription: \n"+
                           "      .... \n"+
                           " ....");
 
       System.out.println (" ");
   }

   private static void processGlobalAttributes (JsonArray globalAttrArray)
                                                throws CDFException {
       long dataTypeu = 0;
       int withDataType = 0;
       Object outs = null;
       for (JsonValue attrInfo : globalAttrArray) {
         for (String attrName: ((JsonObject)attrInfo).keySet()) {
           if (progress) System.out.println("  "+attrName);
           Attribute attr  = Attribute.create(cdf, attrName, GLOBAL_SCOPE);
           JsonArray entries = ((JsonObject)attrInfo).getJsonArray(attrName);
           for (int ii = 0; ii < entries.size(); ++ii) {
             JsonObject entry = entries.getJsonObject(ii);
             for (String entryID: entry.keySet()) {
               Object data = (Object)entry.get(entryID);
               if (progress) System.out.println("      "+entryID+":"+data);
               if (data instanceof JsonArray) {
                 int num = ((JsonArray)data).size();
                 Object v1 = ((JsonArray)data).get(0);
                 if (v1 instanceof JsonObject) {
                   try {
                     JsonObject one = null, two = null;
                     one = (JsonObject) ((JsonArray)data).get(0);
                     two = (JsonObject) ((JsonArray)data).get(1);
                     if (one instanceof JsonObject) {
                       String dt = one.getString("DataType");
                       dataTypeu = CDFUtils.getDataTypeValue(dt);
                       Object des = two.get("Value");
                       withDataType = 1;
                       outs = getData(des, dataTypeu);
                     } else {
                       outs = getData(data, 0);
                     }  
                   } catch (Exception exx) {
                     dataTypeu = 0;
                     outs = getData(data, dataTypeu);
                   }
                 } else
                   outs = getData(data, 0);
                 Entry.create(attr, Integer.valueOf(entryID),
                              dataType, outs);
               } else {
                 outs = getData(data, 0);
                 Entry.create(attr, Integer.valueOf(entryID),
                              dataType, outs); 
               } 
             }
           }
         }
       }
   }

   private static Variable processVariableSpec (String varName,
                                                Object values)
                                                throws CDFException {

       Object padValue = null;
       varPadValue = null;
       varSparseRec = NO_SPARSERECORDS;
       long blockingFactor = -1;
       int items = ((JsonArray)values).size();
       varDataType = varNumElems = varNumDims = varMaxWritten = -1;
       compression = -1;
       compLvl = 0;
       for (int jj = 0; jj < items; ++jj) {
         Object data = (Object) ((JsonArray)values).get(jj);
         if (data instanceof JsonObject) {
           for (String keyx: ((JsonObject)data).keySet()) {
             Object des = ((JsonObject)data).get(keyx);
             if (progress) System.out.println("      "+keyx+":"+des);
             if (keyx.equalsIgnoreCase("varname")) {
             } else if (keyx.equalsIgnoreCase("datatype")) {
               String dt = ((JsonObject)data).getString(keyx);
               varDataType = CDFUtils.getDataTypeValue(dt);
             } else if (keyx.equalsIgnoreCase("numelements")) {
               varNumElems = (long) ((JsonObject)data).getInt(keyx);
             } else if (keyx.equalsIgnoreCase("numdims")) {
               varNumDims = (long) ((JsonObject)data).getInt(keyx);
             } else if (keyx.equalsIgnoreCase("dimsizes")) {
               JsonArray ds = ((JsonObject)data).getJsonArray(keyx);
               for (int j = 0; j < (int)varNumDims; ++j) {
                 varDimSizes[j] = (long) ds.getInt(j);
               }
             } else if (keyx.equalsIgnoreCase("recvariance")) {
               String rv = ((JsonObject)data).getString(keyx);
               if (rv.equalsIgnoreCase("vary")) varRecVary = VARY;
               else varRecVary = NOVARY;
             } else if (keyx.equalsIgnoreCase("dimvariances")) {
               JsonArray dv = ((JsonObject)data).getJsonArray(keyx);
               for (int j = 0; j < (int)varNumDims; ++j) {
                 String dv1 = dv.getString(j);
                 if (dv1.equalsIgnoreCase("vary"))
                   varDimVariances[j] = VARY;
                 else
                   varDimVariances[j] = NOVARY;
               }
             } else if (keyx.equalsIgnoreCase("compression")) {
               String cp = ((JsonObject)data).getString(keyx);
               int len = cp.indexOf('.');
               if (len != -1) {
                 String cType = cp.substring(0, cp.indexOf('.'));
                 String cLvl = cp.substring(cp.indexOf('.')+1);
                 compression = CDFUtils.getLongCompressionType(cType);
                 compLvl = Long.valueOf(cLvl);
               } else {
                 compression = CDFUtils.getLongCompressionType(cp);
                 compLvl = 0L;
               }
             } else if (keyx.equalsIgnoreCase("blockingfactor")) {
               blockingFactor = (long) ((JsonObject)data).getInt(keyx);
             } else if (keyx.equalsIgnoreCase("sparserecords")) {
               String sr = ((JsonObject)data).getString(keyx);
               varSparseRec = CDFUtils.getLongSparseRecord(sr);
             } else if (keyx.equalsIgnoreCase("numwrittenrecords")) {
               varNumWritten = (long) ((JsonObject)data).getInt(keyx);
             } else if (keyx.equalsIgnoreCase("maxwrittenrec")) {
               varMaxWritten = (long) ((JsonObject)data).getInt(keyx);
             } else if (keyx.equalsIgnoreCase("padvalue")) {
               padValue = (Object) ((JsonObject)data).get(keyx);
             } else
               System.out.println("NOT handling... "+keyx);
           }
         }
       }

       if (progress) {
         System.out.print("***** Creating... var:"+varName+" "+" type:"+
                          CDFUtils.getStringDataType(varDataType)+
                          " numElms="+varNumElems+" numDims="+varNumDims+" ");
         if (varNumDims > 0) {
           System.out.print("dimSize=[");
           for (int ll= 0; ll < (int)varNumDims; ++ll) {
             System.out.print(varDimSizes[ll]);
             if (ll < (varNumDims-1)) System.out.print(",");
             if (ll == (varNumDims-1)) System.out.print("] ");
           }
         }
         System.out.println("RecVary="+(varRecVary==-1?"T":"F"));
       }

       if (varDataType == -1 || varNumElems == -1 || varNumDims == -1)
         return null;
       var = Variable.create(cdf, varName, varDataType, varNumElems,
                             varNumDims, varDimSizes, varRecVary, 
                             varDimVariances);
       varFillVal = null;
       if (padValue != null) {
         varPadValue = setData1 (padValue);
         var.setPadValue(varPadValue);
       }

       if (blockingFactor != -1)
         var.setBlockingFactor(blockingFactor);
       if (varSparseRec != NO_SPARSERECORDS)
         var.setSparseRecords(varSparseRec);

       if (toCompress) {
         if (compression != -1)
           var.setCompression(compression, new long[] {compLvl});
       }

       return var;
   }

   private static void processVariableAttributes (Object values)
                                                  throws CDFException {
       int items = ((JsonArray)values).size();
       Object outs = null;
       int withDataType = 0;
       long dataTypeu = 0;
       for (int jj = 0; jj < items; ++jj) {
         Attribute attr = null;
         JsonObject entry = ((JsonArray)values).getJsonObject(jj);
         for (String keyx: entry.keySet()) {
           withDataType = 0;
           Object des = (Object)entry.get(keyx);
           dataTypeu = 0;
           //                                        attr: value(s)
           if (progress) System.out.println("      "+keyx+":"+des);
           try {
             attr = Attribute.create(cdf, keyx, VARIABLE_SCOPE);
           } catch (CDFException ss) {
             attr = cdf.getAttribute(keyx);
           }
           if (des instanceof JsonArray) {
             // des is an array of values (integer or floating or string) or
             // an array of jsonObjects
             int nItems = ((JsonArray)des).size();
             Object v1 = ((JsonArray)des).get(0);
             if (v1 instanceof JsonObject) {
               try {
                 JsonObject one = null, two = null;
                 one = (JsonObject) ((JsonArray)des).get(0);
                 two = (JsonObject) ((JsonArray)des).get(1);
                 if (one instanceof JsonObject) {
                   String dt = one.getString("DataType");
                   dataTypeu = CDFUtils.getDataTypeValue(dt);
                   des = two.get("Value");
                   withDataType = 1;
                 }
               } catch (Exception exx) {
                 // des is any array of values
                 dataTypeu = 0;
               }
               dataType = varDataType;
               vAttrName = keyx;
               outs = getData(des, dataTypeu);
               if (withDataType == 0) {
                 if (useVarDataType(keyx)) {
                   Object outs2 = changeData(dataType, varDataType, outs);
                   if (keyx.equalsIgnoreCase("fillval"))
                     varFillVal = outs2;
                 }
               }
               if (outs instanceof String[]) {
                 // array of strings
                 int sItems = ((String[])outs).length;
                 StringBuffer sb = new StringBuffer();
                 for (int ii = 0; ii < sItems; ++ii) {
                   sb.append(((String[])outs)[ii]);
                   if (ii < (sItems - 1)) sb.append(STRINGDELIMITER);
                 }
                 var.putEntry(attr, (withDataType==1?dataTypeu:CDF_CHAR),
                             sb.toString());
               } else {
                 var.putEntry(attr, (withDataType==1?dataTypeu:dataType),
                             outs);
               }
             } else {
               if (useVarDataType(keyx)) dataTypeY = var.getDataType();
               else dataTypeY = -1;
               Object out2 = buildDataObject (dataTypeY, des);
               var.putEntry(attr, dataTypeY, out2);
             }
           } else if (des instanceof JsonString) {
             String str = (String) getData(des, CDF_CHAR);
             if (useVarDataType(keyx)) {
               Object out = parseContents (str, varDataType);
               if (out != null)
                 var.putEntry(attr, varDataType, out);
                else
                 var.putEntry(attr, CDF_CHAR, str);
             } else {
               var.putEntry(attr, CDF_CHAR, str);
             }
           } else {
             dataType = varDataType;
             vAttrName = keyx;
             outs = getData(des, 0);
             if (withDataType == 0) {
               if (useVarDataType(keyx)) {
                 outs = changeData(dataType, varDataType, outs);
                 if (keyx.equalsIgnoreCase("fillval"))
                   varFillVal = outs;
               }
             }
             var.putEntry(attr, dataType, outs);
           }
         }

       }
   }

   private static void processVariableData (Object varDatax)
                                            throws CDFException {
     try {
       int recNum, totalItems;
       recNum = (int) (varMaxWritten==-1?(varNumWritten==-1?-1:varNumWritten):
                                         (varMaxWritten+1));
       if (recNum <= 0) {
         if (varDatax instanceof JsonArray)
           recNum = ((JsonArray)varDatax).size();
         else
           recNum = 1;
       }
       if (!var.getRecVariance()) recNum = 1;
       int nBytes = 1;
       Object realData = null;
       Object outs = null;
       varRecItems = 1;
       for (int iy=0; iy < varNumDims; ++iy) varRecItems *= varDimSizes[iy];
       if (varDataType == CDF_CHAR || varDataType == CDF_UCHAR)
         nBytes = (int) varRecItems * (int) varNumElems * recNum;
         totalItems = (int) (varRecItems * recNum);
       if (progress)
         System.out.println("      recNum="+recNum+" total values="+totalItems);
       if (varDataType == CDF_INT1 || varDataType == CDF_BYTE) {
           outs = (Object) new byte[totalItems];
           if (varSparseRec != NO_SPARSERECORDS)
             realData = (Object) new byte[(int)varRecItems];
       } else if (varDataType == CDF_INT2 || varDataType == CDF_UINT1) {
           outs = (Object) new short[totalItems];
           if (varSparseRec != NO_SPARSERECORDS)
             realData = (Object) new short[(int)varRecItems];
       } else if (varDataType == CDF_INT4 || varDataType == CDF_UINT2) {
           outs = (Object) new int[totalItems];
           if (varSparseRec != NO_SPARSERECORDS)
             realData = (Object) new int[(int)varRecItems];
       } else if (varDataType == CDF_INT8 || varDataType == CDF_UINT4 ||
                    varDataType == CDF_TIME_TT2000) {
           outs = (Object) new long[totalItems];
           if (varSparseRec != NO_SPARSERECORDS)
             realData = (Object) new long[(int)varRecItems];
       } else if (varDataType == CDF_REAL4 || varDataType == CDF_FLOAT) {
           outs = (Object) new float[totalItems];
           if (varSparseRec != NO_SPARSERECORDS)
             realData = (Object) new float[(int)varRecItems];
       } else if (varDataType == CDF_REAL8 || varDataType == CDF_DOUBLE ||
                    varDataType == CDF_EPOCH) {
           outs = (Object) new double[totalItems];
           if (varSparseRec != NO_SPARSERECORDS)
             realData = (Object) new double[(int)varRecItems];
       } else if (varDataType == CDF_EPOCH16) {
           outs = (Object) new double[totalItems*2];
           if (varSparseRec != NO_SPARSERECORDS)
             realData = (Object) new double[(int)varRecItems*2];
       } else if (varDataType == CDF_CHAR || varDataType == CDF_UCHAR) {
           outs = (Object) new byte[nBytes];
           if (varSparseRec != NO_SPARSERECORDS)
             realData = (Object) new byte[(int)(varRecItems*varNumElems)];
       }

       if (toCompress) {
         if (compression == -1) {
           long nValues;
           boolean toDouble = false;
           if (varDataType == CDF_EPOCH16) toDouble = true;
           nValues = varRecItems * varNumElems * (toDouble?2:1);
           nValues *= getDataTypeSize(varDataType);
           if (nValues > 1000) { // compress if > 1k
             compression = GZIP_COMPRESSION;
             compLvl = 6;
             var.setCompression(compression, new long[] {compLvl});
           }
         }
       }

       if (varSparseRec == NO_SPARSERECORDS) {
         if (varDatax instanceof JsonArray)
           realData = setData ((Object) varDatax, (Object)outs);
         else
           realData = setData1(varDatax);
         var.putRecords(0L, (long) recNum, realData);
       } else {
         Object filledData = null;
         boolean virtual;
         if (varSparseRec == PAD_SPARSERECORDS) {
           if (varFillVal != null) filledData = varFillVal;
           else filledData = varPadValue;
         }
         if (varDatax instanceof JsonArray) {
           for (int ii = 0; ii < recNum; ++ii) {
             Object data = (Object) ((JsonArray)varDatax).get(ii);
             if (data instanceof JsonArray) {
               outs = setData (data, outs);
               moveOneRecord (realData, 0, outs, (int) (index-varRecItems),
                              (int) varRecItems, varNumElems);
             } else
               realData = setData1(data);
             virtual = checkForVirtual (realData, filledData);
             if (!virtual) {
               var.putRecord((long)ii, realData);
               if (varSparseRec == PREV_SPARSERECORDS) 
                 filledData = realData;
             }
           } // for loop
         } else {
           realData = setData1(varDatax);
           virtual = checkForVirtual (realData, filledData);
           if (!virtual) {
             var.putRecord((long)0, realData);
           }
         }
       }
     } catch (Exception ex) {
       System.out.println("*** Error: "+ex);
     }
   }

   private static boolean  checkForVirtual (Object data, Object filledData) {

       if (filledData == null) return false;
       String signature = CDFUtils.getSignature(data);
       String sig2 = CDFUtils.getSignature(filledData);
       if (signature.charAt(0) == '[') {
         if (varDataType == CDF_INT1 || varDataType == CDF_BYTE) {
           int itemN = ((byte[])data).length;
           for (int ik = 0; ik < itemN; ++ik) {
             if (sig2.charAt(0) == '[') {
               if (((byte[])data)[ik] != ((byte[])filledData)[ik])
                 return false;
             } else {
               if (((byte[])data)[ik] != ((Byte)filledData).byteValue())
                 return false;
             }
           }
           return true;
         } else if (varDataType == CDF_INT2 || varDataType == CDF_UINT1) {
           int itemN = ((short[])data).length;
           for (int ik = 0; ik < itemN; ++ik) {
             if (sig2.charAt(0) == '[') {
               if (((short[])data)[ik] != ((short[])filledData)[ik])
                 return false;
             } else {
               if (((short[])data)[ik] != ((Short)filledData).shortValue())
                 return false;
             }
           }
           return true;
         } else if (varDataType == CDF_INT4 || varDataType == CDF_UINT2) {
           int itemN = ((int[])data).length;
           for (int ik = 0; ik < itemN; ++ik) {
             if (sig2.charAt(0) == '[') {
               if (((int[])data)[ik] != ((int[])filledData)[ik])
                 return false;
             } else {
               if (((int[])data)[ik] != ((Integer)filledData).intValue())
                 return false;
             }
           }
           return true;
         } else if (varDataType == CDF_INT8 || varDataType == CDF_UINT4 ||
                    varDataType == CDF_TIME_TT2000) {
           int itemN = ((long[])data).length;
           for (int ik = 0; ik < itemN; ++ik) {
             if (sig2.charAt(0) == '[') {
               if (((long[])data)[ik] != ((long[])filledData)[ik])
                 return false;
             } else {
               if (((long[])data)[ik] != ((Long)filledData).longValue())
                 return false;
             }
           }
           return true;
         } else if (varDataType == CDF_REAL4 || varDataType == CDF_FLOAT) {
           int itemN = ((float[])data).length;
           for (int ik = 0; ik < itemN; ++ik) {
             if (sig2.charAt(0) == '[') {
               if (((float[])data)[ik] != ((float[])filledData)[ik])
                 return false;
             } else {
               if (((float[])data)[ik] != ((Float)filledData))
                 return false;
             }
           }
           return true;
         } else if (varDataType == CDF_REAL8 || varDataType == CDF_DOUBLE ||
                    varDataType == CDF_EPOCH) {
           int itemN = ((double[])data).length;
           for (int ik = 0; ik < itemN; ++ik) {
             if (sig2.charAt(0) == '[') {
               if (((double[])data)[ik] != ((double[])filledData)[ik])
                 return false;
             } else {
               if (((double[])data)[ik] != ((Double)filledData))
                 return false;
             }
           }
           return true;
         }
       } else {
         if (varDataType == CDF_INT1 || varDataType == CDF_BYTE) {
           if (((Byte)data).byteValue() != ((Byte)filledData).byteValue())
             return false;
           else
             return true;
         } else if (varDataType == CDF_INT2 || varDataType == CDF_UINT1) {
           if (((Short)data).shortValue() != ((Short)filledData).shortValue())
             return false;
           else
             return true;
         } else if (varDataType == CDF_INT4 || varDataType == CDF_UINT2) {
           if (((Integer)data).intValue() != ((Integer)filledData).intValue())
             return false;
           else
             return true;
         } else if (varDataType == CDF_INT8 || varDataType == CDF_UINT4 ||
                    varDataType == CDF_TIME_TT2000) {
         } else if (varDataType == CDF_REAL4 || varDataType == CDF_FLOAT) {
           if (((Float)data) != ((Float)filledData))
             return false;
           else
             return true;
         } else if (varDataType == CDF_REAL8 || varDataType == CDF_DOUBLE ||
                    varDataType == CDF_EPOCH) {
           if (((Double)data) != ((Double)filledData))
             return false;
           else
             return true;
         } else
           return false;
       }
       return false;
   }

   private static int getDimSize (Object obj) {
       String sig = CDFUtils.getSignature(obj);
       String what = sig.substring(0,2);
       if (what.equals("[I")) return ((int[])obj).length;
       else if (what.equals("[B")) return ((byte[])obj).length;
       else if (what.equals("[J")) return ((long[])obj).length;
       else if (what.equals("[S")) return ((short[])obj).length;
       else if (what.equals("[F")) return ((float[])obj).length;
       else if (what.equals("[D")) return ((double[])obj).length;
       return 1;
   }

   private static int getDataTypeSize (long dataType) {
       int size;
       switch ((int)dataType) {
         case (int)CDF_BYTE:
         case (int)CDF_INT1:
         case (int)CDF_UINT1:
         case (int)CDF_CHAR:
         case (int)CDF_UCHAR:
           size = 1;
           break;
         case (int)CDF_INT2:
         case (int)CDF_UINT2:
           size = 2;
           break;
         case (int)CDF_INT4:
         case (int)CDF_UINT4:
         case (int)CDF_REAL4:
         case (int)CDF_FLOAT:
           size = 4;
           break;
         case (int)CDF_INT8:
         case (int)CDF_TIME_TT2000:
         case (int)CDF_REAL8:
         case (int)CDF_DOUBLE:
         case (int)CDF_EPOCH:
           size = 8;
           break;
         case (int)CDF_EPOCH16:
           size = 16;
           break;
         default:
           size = 1;
           break;
       }
       return size;
   }

   public static Object parseContents (String data, long dataType) {                                     

       if (data.charAt(0) == '"')
         data = data.substring(1, data.length()-1);
       Vector vec = new Vector();
       StringTokenizer st = new StringTokenizer(data, ",");
       if (st.countTokens() == -1) {
         return null;
       }
       while (st.hasMoreTokens()) {
         vec.addElement(st.nextToken());
       }
       int filterElementsNum = vec.size();
       if (dataType == CDF_CHAR || dataType == CDF_UCHAR) {
            String aStr;
            aStr = data;
            if (data.indexOf("\\\"") != -1) {
              aStr = data.replaceAll("\\\\\"", "\"");
            }
            if (aStr.indexOf("\\n") != -1) {
              aStr = aStr.replace("\\n", "\n");
            }
            return aStr;
       } else if (dataType == CDF_BYTE || dataType == CDF_INT1) {
          byte[] aByte = new byte[filterElementsNum];
          if (filterElementsNum == 1) {
            try {
              aByte[0] = Byte.valueOf(data);
            } catch (Exception b1) {
              if (progress) System.out.println("***** Invalid INT1: "+data+" => out of range");
              return null;
            }
          } else {
            String ttt;
            for (int i = 0; i < filterElementsNum; i++) {
              ttt = ((String)(vec.elementAt(i))).trim();
              try {
                aByte[i] = Byte.valueOf(ttt);
              } catch (Exception b2) {
                if (progress) System.out.println("***** Invalid INT1: "+ttt+" => out of range");
                return null;
              }
            }
          }
          return aByte;
       } else if (dataType == CDF_UINT1 || dataType == CDF_INT2) {
          short[] aShort = new short[filterElementsNum];
          if (filterElementsNum == 1) {
            try {
              aShort[0] = Short.valueOf(data);
              if (dataType == CDF_UINT1) {
                if (aShort[0] < 0 || aShort[0] > 255) {
                  if (progress) System.out.println("***** Invalid UINT1: "+aShort[0]+" => out of range");
                  return null;
                }
              }
            } catch (Exception s1) {
              if (progress) System.out.println("***** Invalid INT2: "+data);
              return null;
            }
          } else {
            String ttt;
            for (int i = 0; i < filterElementsNum; i++) {
              ttt = ((String)(vec.elementAt(i))).trim();
              try {
                aShort[i] = Short.valueOf(ttt);
                if (dataType == CDF_UINT1) {
                  if (aShort[i] < 0 || aShort[i] > 255) {
                    if (progress) System.out.println("***** Invalid UINT1: "+aShort[i]+" => out of range");
                    return null;
                  }
                }
              } catch (Exception s2) {
                if (progress) System.out.println("***** Invalid INT2: "+ttt);
                return null;
              }
            }
          }
          return aShort;
       } else if (dataType == CDF_UINT2 || dataType == CDF_INT4) {
          int[] aInteger = new int[filterElementsNum];
          if (filterElementsNum == 1) {
            try {
              aInteger[0] =  Integer.valueOf(data);
              if (dataType == CDF_UINT2) {
                if (aInteger[0] < 0 || aInteger[0] > 65535) {
                  if (progress) System.out.println("***** Invalid UINT2: "+aInteger[0]+" => out of range");
                  return null;
                }
              }
            } catch (Exception i1) {
              if (progress) System.out.println("***** Invalid INT4: "+data);
              return null;
            }
          } else {
            String ttt;
            for (int i = 0; i < filterElementsNum; i++) {
              ttt = ((String)(vec.elementAt(i))).trim();
              try {
                aInteger[i] = Integer.valueOf(ttt);
                if (dataType == CDF_UINT2) {
                  if (aInteger[i] < 0 || aInteger[i] > 65535) {
                    if (progress) System.out.println("***** Invalid UINT2: "+aInteger[i]+" => out of range");
                    return null;
                  }
                }
              } catch (Exception i2) {
                if (progress) System.out.println("***** Invalid INT4: "+ttt);
                return null;
              }
            }
          }
          return aInteger;
       } else if (dataType == CDF_UINT4 || dataType == CDF_INT8) {
          long[] aLong = new long[filterElementsNum];
          if (filterElementsNum == 1) {
            try {
              aLong[0] = Long.valueOf(data);
              if (dataType == CDF_UINT4) {
                if (aLong[0] < 0 || aLong[0] > 4294967295L ) {
                  if (progress) System.out.println("***** Invalid UINT4: "+aLong[0]+" => out of range");
                  return null;
                }
              }
            } catch (Exception l1) {
              if (progress) System.out.println("***** Invalid INT8: "+data);
              return null;
            }  
          } else {
            String ttt;
            for (int i = 0; i < filterElementsNum; i++) {
              ttt = ((String)(vec.elementAt(i))).trim();
              try {
                aLong[i] = Long.valueOf(ttt);
                if (dataType == CDF_UINT4) {
                  if (aLong[i] < 0 || aLong[i] > 4294967295L ) {
                    if (progress) System.out.println("***** Invalid UINT4: "+aLong[i]+" => out of range");
                    return null;
                  }
                }
              } catch (Exception l2) {
                if (progress) System.out.println("***** Invalid INT8: "+ttt);
                return null;
              }
            }
          }
          return aLong;
       } else if (dataType == CDF_FLOAT || dataType == CDF_REAL4) {
          float[] aFloat = new float[filterElementsNum];
          if (filterElementsNum == 1) {
            aFloat[0] = Float.valueOf(data);
          } else {
            for (int i = 0; i < filterElementsNum; i++)
              aFloat[i] = Float.valueOf(((String)(vec.elementAt(i))).trim());
          }
          return aFloat;
       } else if (dataType == CDF_REAL8 || dataType == CDF_DOUBLE) {
          double[] aDouble = new double[filterElementsNum];
          if (filterElementsNum == 1) {
            aDouble[0] = Double.valueOf(data);
          } else {
            for (int i = 0; i < filterElementsNum; i++)
              aDouble[i] = Double.valueOf(((String)(vec.elementAt(i))).trim());
          }
          return aDouble;
       } else if (dataType == CDF_EPOCH) {
            double[] aDouble = new double[filterElementsNum];
            if (filterElementsNum == 1) {
              try {
                Double.parseDouble(data);
                aDouble[0] = Double.valueOf(data);
              } catch (Exception d1) {
                try {
                  aDouble[0] = Epoch.toParse(data);
                } catch (CDFException e) {
                  if (progress)
                    System.out.println("***** Invalid Epoch: "+data+" => Format?");
                  return null;
                }
              }
            } else {
              for (int i = 0; i < filterElementsNum; i++) {
                String ttt = ((String) vec.elementAt(i)).trim();
                if (ttt.indexOf(":") == -1)
                try {
                  Double.parseDouble(ttt);
                  aDouble[i] = Double.valueOf(ttt);
                } catch (Exception d2) {
                  try {
                    aDouble[i] = Epoch.toParse(ttt);
                  } catch (CDFException e) {
                    if (progress)
                      System.out.println("***** Invalid Epoch: "+ttt+" => Format?");
                    return null;
                  }
                }
              }
            }
            return aDouble;
       } else if (dataType == CDF_EPOCH16) {
            if (filterElementsNum == 1) {
              double[] aDouble = new double[2];
              try {
                Double.parseDouble(data);
                aDouble[0] = Double.valueOf(data);
                aDouble[1] = 0.0;
              } catch (Exception d1) {
                try {
                  aDouble = (double[]) Epoch16.toParse((String)data);
                } catch (CDFException e) {
                  if (progress)
                    System.out.println("***** Invalid Epoch16: "+data+" => Format?");
                  return null;
                }
              }
              return aDouble;
            } else {
              double[][] aDouble = new double[filterElementsNum][2];
              double[] aaa = new double[2];
              for (int i = 0; i < filterElementsNum; i++) {
                String ttt = ((String) vec.elementAt(i)).trim();
                try {
                  Double.parseDouble(ttt);
                  aDouble[i][0] = Double.valueOf(ttt);
                  aDouble[i][1] = 0.0;
                } catch (Exception d2) {
                  try {
                    aaa = (double[]) Epoch16.toParse(ttt);
                    aDouble[i][0] = aaa[0];
                    aDouble[i][1] = aaa[1];
                  } catch (CDFException e) {
                    if (progress)
                      System.out.println("***** Invalid Epoch16: "+ttt+" => Format?");
                    return null;
                  }
                }
              }
              return aDouble;
            }
       } else if (dataType == CDF_TIME_TT2000) {
            long[] aLong = new long[filterElementsNum];
            if (filterElementsNum == 1) {
              try {
                Long.parseLong(data);
                aLong[0] = Long.valueOf(data);
              } catch (Exception l1) {
                try {
                  aLong[0] = (long) CDFTT2000.toParse((String)data);
                } catch (CDFException e) {
                  if (progress)
                    System.out.println("***** Invalid tt2000: "+data+" => Format?");
                  return null;
                }
              }
            } else {
              for (int i = 0; i < filterElementsNum; i++) {
                String ttt = ((String) vec.elementAt(i)).trim();
                try {
                   Long.parseLong(ttt);
                  aLong[i] = Long.valueOf(ttt);
                } catch (Exception l2) {
                  try {
                    aLong[i] = (long) CDFTT2000.toParse(ttt);
                  } catch (CDFException e) {
                    if (progress)
                      System.out.println("***** Invalid tt2000: "+ttt+" => Format?");
                    return null;
                  }
                }
              }
            }
            return aLong;
       } return null;
   }

   private static boolean useVarDataType (String key) {
       if (key == null) return false;
       else if (key.equalsIgnoreCase("validmin") ||
                key.equalsIgnoreCase("validmax") ||
                key.equalsIgnoreCase("scalemin") ||
                key.equalsIgnoreCase("scalemax") ||
                key.equalsIgnoreCase("fillval")) return true;
       else return false;
   }

   /*****************************************************************/
   /*  Build the _data object based on the passed data type and     */
   /*  Json array object for CDF.                                   */
   /*****************************************************************/

   private static Object buildDataObject(long dataTypeX, Object des) {
       Object _data = null;
       int numValues = (int) ((JsonArray)des).size();
       Object v1 = null;
       switch ((int)dataTypeX) {
       case (int)CDF_BYTE:
       case (int)CDF_INT1:
            if (numValues > 1) {
                _data = new byte [numValues];
                for (int i=0; i<numValues; i++) {
                  String str = ((JsonNumber)((JsonArray)des).get(i)).toString();
                  ((byte [])_data)[i] = Byte.valueOf(str);
                }
            } else {
                _data = new byte[1];
                String str = ((JsonNumber)des).toString();
                ((byte[])_data)[0] = Byte.valueOf(str);
            }
            break;
       case (int)CDF_INT2:
       case (int)CDF_UINT1:
            if (numValues > 1) {
                _data = new short [numValues];
                for (int i=0; i<numValues; i++) {
                  String str = ((JsonNumber)((JsonArray)des).get(i)).toString();
                  ((short [])_data)[i] = Short.valueOf(str);
                }
            } else {
                _data = new short[1];
                String str = ((JsonNumber)des).toString();
                ((short[])_data)[0] = Short.valueOf(str);
            }
            break;
       case (int)CDF_INT4:
       case (int)CDF_UINT2:
            if (numValues > 1) {
                _data = new int [numValues];
                for (int i=0; i<numValues; i++) {
                  String str = ((JsonNumber)((JsonArray)des).get(i)).toString();
                  ((int [])_data)[i] = Integer.valueOf(str);
                }
            } else {
                _data = new int[1];
                String str = ((JsonNumber)des).toString();
                ((int[])_data)[0] = Integer.valueOf(str);
            }
            break;
       case (int)CDF_UINT4:
       case (int)CDF_INT8:
            if (numValues > 1) {
                _data = new long [numValues];
                for (int i=0; i<numValues; i++) {
                  String str = ((JsonNumber)((JsonArray)des).get(i)).toString();
                  ((long [])_data)[i] = Long.valueOf(str);
                }
            } else {
                _data = new long[1];
                String str = ((JsonNumber)des).toString();
                ((long[])_data)[0] = Long.valueOf(str);
            }
            break;
        case (int)CDF_TIME_TT2000:
            if (numValues > 1) {
                _data = new long [numValues];
                for (int i=0; i<numValues; i++) {
                  v1 = (Object) ((JsonArray)des).get(i);
                  if (v1 instanceof JsonNumber) {
                    String str = ((JsonNumber)v1).toString();
                    ((long [])_data)[i] = Long.valueOf(str);
                  } if (v1 instanceof JsonString) {
                    String str = ((JsonString)v1).toString();
                    try {
                      ((long [])_data)[i] = CDFTT2000.toParse(str);
                    } catch (Exception ex) {
                      ((long [])_data)[i] = ILLEGAL_TT2000_VALUE;
                    }
                  }
                }
            } else {
                _data = new long[1];
                if (des instanceof JsonNumber) {
                  String str = ((JsonNumber)des).toString();
                  ((long[])_data)[0] = Long.valueOf(str);
                } else if (des instanceof JsonString) {
                  String str = ((JsonString)des).toString();
                  try {
                    ((long[])_data)[0] = Long.valueOf(CDFTT2000.toParse(str));
                  } catch (Exception ex) {
                    ((long [])_data)[0] = ILLEGAL_TT2000_VALUE;
                  }
                }
            }
            break;
       case (int)CDF_REAL4:
       case (int)CDF_FLOAT:
            if (numValues > 1) {
                _data = new float [numValues];
                for (int i=0; i<numValues; i++) {
                  String str = ((JsonNumber)((JsonArray)des).get(i)).toString();
                  ((float [])_data)[i] = Float.valueOf(str);
                }
            } else {
                _data = new float[1];
                String str = ((JsonNumber)des).toString();
                ((float[])_data)[0] = Float.valueOf(str);
            }
            break;
       case (int)CDF_REAL8:
       case (int)CDF_DOUBLE:
            if (numValues > 1) {
                _data = new double [numValues];
                for (int i=0; i<numValues; i++) {
                  String str = ((JsonNumber)((JsonArray)des).get(i)).toString();
                  ((double [])_data)[i] = Double.valueOf(str);
                }
            } else {
                _data = new double[1];
                String str = ((JsonNumber)des).toString();
                ((double[])_data)[0] = Double.valueOf(str);
            }
            break;
       case (int)CDF_EPOCH:
            if (numValues > 1) {
                _data = new double [numValues];
                for (int i=0; i<numValues; i++) {
                  v1 = (Object) ((JsonArray)des).get(i);
                  if (v1 instanceof JsonNumber) {
                    String str = ((JsonNumber)v1).toString();
                    ((double [])_data)[i] = Double.valueOf(str);
                  } else if (v1 instanceof JsonString) {
                    String str = ((JsonString)v1).toString();
                    try {
                      ((double [])_data)[i] = Epoch.toParse(str);
                    } catch (Exception ex) {
                      ((double [])_data)[i] = ILLEGAL_EPOCH_VALUE;
                    }
                  }
                }
            } else {
                _data = new double[1];
                if (des instanceof JsonNumber) {
                  String str = ((JsonNumber)des).toString();
                  ((double[])_data)[0] = Double.valueOf(str);
                } else if (des instanceof JsonString) {
                  String str = ((JsonString)des).toString();
                  try {
                    ((double[])_data)[0] = Double.valueOf(Epoch.toParse(str));
                  } catch (Exception ex) {
                      ((double [])_data)[0] = ILLEGAL_EPOCH_VALUE;
                    }
                }
            }
            break;
       case (int)CDF_EPOCH16:
            double tmp; double[] epoch16 = new double[2];
            v1 = (Object) ((JsonArray)des).get(0);
            if (v1 instanceof JsonNumber) {
              _data = new double [numValues];
              for (int i = 0; i<numValues/2; i++) {
                String str1 = ((JsonNumber)((JsonArray)des).get(2*i)).toString();
                String str2 = ((JsonNumber)((JsonArray)des).get(2*i+1)).toString();
                ((double[])_data)[2*i] = Double.valueOf(str1);
                ((double[])_data)[2*i+1] = Double.valueOf(str2);
              }
            } else if (v1 instanceof JsonString) {
              _data = new double [2*numValues];
              for (int i = 0; i<numValues; i++) {
                String str = ((JsonString)((JsonArray)des).get(i)).toString();
                try {
                  epoch16 = Epoch16.toParse (str);
                } catch (Exception ex) {
                  epoch16[0] = ILLEGAL_EPOCH_VALUE;
                  epoch16[1] = ILLEGAL_EPOCH_VALUE;
                }
                ((double[])_data)[2*i] = epoch16[0];
                ((double[])_data)[2*i+1] = epoch16[1];
              }
            }
            break;
       default:
            if (numValues > 1) {
              Object v0 = (Object) ((JsonArray)des).get(0);
              if (v0 instanceof JsonNumber) {
                if (((JsonNumber)v0).isIntegral()) {
                  try {
                    _data = new int[numValues];
                    for (int i = 0; i < numValues; ++i) {
                      v1 = (Object) ((JsonArray)des).get(i);
                      String str = ((JsonNumber)v1).toString();
                      ((int[])_data)[i] = Integer.valueOf(str);
                    }
                    dataTypeY = CDF_INT4;
                  } catch (Exception ex11) {
                    try { 
                      _data = new long[numValues];
                      for (int i = 0; i < numValues; ++i) {
                        v1 = (Object) ((JsonArray)des).get(i);
                        String str = ((JsonNumber)v1).toString();
                        ((long[])_data)[i] = Long.valueOf(str);
                      }
                      dataTypeY = CDF_INT8;
                    } catch (Exception ex22) {
                      System.out.println("Invalid Json integer... value:"+des+
                                         " dt:"+dataTypeY+" "+ex22);
                      return null;
                    }
                  }
                } else { // floating value
                  _data = new double[numValues];
                  for (int i = 0; i < numValues; ++i) {
                    v1 = (Object) ((JsonArray)des).get(i);
                    String str = ((JsonNumber)v1).toString();
                    ((double[])_data)[i] = Double.valueOf(str);
                  }
                  dataTypeY = CDF_DOUBLE;
                }
              } else if (v0 instanceof JsonString) {
                _data = new String();
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < numValues; ++i) {
                  v1 = (Object) ((JsonArray)des).get(i);
                  String str = ((JsonString)v1).toString();
                  if (str.startsWith("\"") && str.endsWith("\""))
                    str = str.substring(1, str.length()-1);
                  sb = sb.append(str);
                  if (i != (numValues - 1)) sb = sb.append(" ");
                }
                _data = new String(sb.toString());
                dataTypeY = CDF_CHAR;
              }
            } else {
              if (des instanceof JsonNumber) {
                String str = ((JsonNumber)des).toString();
                if (((JsonNumber)des).isIntegral()) {
                  try {
                    _data = new int[1];
                    dataTypeY = CDF_INT4;
                    _data =  parseContents (str, dataTypeY);
                  } catch (Exception ei4) {
                    try {
                      _data = new long[1];
                      dataTypeY = CDF_INT8;
                      _data = parseContents (str, dataTypeY);
                    } catch (Exception ei8) {
                      System.out.println("Invalid Json integer... value:"+str+
                                         " dt:"+dataTypeY+" "+ei8);
                      return null;
                    }
                  }
                } else {
                  _data = new double[1];
                  dataTypeY = CDF_DOUBLE;
                  _data = parseContents (str, dataTypeY);
                }
              } else if (des instanceof JsonString) {
                _data = new String();
                String str = ((JsonString)des).toString();
                if (str.startsWith("\"") && str.endsWith("\""))
                  str = str.substring(1, str.length()-1);
                _data = new String(str);
                dataTypeY = CDF_CHAR;
              }
            }
            break;
       } /* switch (dataTypeX) */
       return _data;
   }

} 

