/******************************************************************************
* Copyright 1996-2014 United States Government as represented by the
* Administrator of the National Aeronautics and Space Administration.
* All Rights Reserved.
******************************************************************************/

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

/**
 */

public class ExportCreateCDF implements CDFConstants, Runnable {

   private ExportCreateCDF exportCreateCDF;
   private BuildProgressPanel progressPanel;
   private ExportCDFTable exportCDFTable;
   private CDFExport myCDFExport;
   private CDF sourceCDF, cdf;
   private String destCDF;

   private int totalItems;
   private int currentProgressValue = 0;
   private int irec;
   private int len;
   private int minLen;
   private int maxLen;
   private int filLen;
   private Object oldMin, newMin;
   private Object oldMax, newMax;
   private Object newFil;

   private Variable variable, newVariable;
   private Vector variableAttributes;
   private Attribute attribute, newAttribute;
   private boolean padValue, compressed;

   private Object minObj = null;
   private Object maxObj = null;
   private Object filObj = null;
   private boolean deleting;

   ExportCreateCDF(CDFExport myCDFExport, ExportCDFTable exportCDFTable) {

      exportCreateCDF = this;
      this.exportCDFTable = exportCDFTable;
      this.myCDFExport = myCDFExport;
      sourceCDF  = myCDFExport.sourceCDF;
      if (myCDFExport.outSelection == 3)
        destCDF = myCDFExport.cdfspec3;
      else
        destCDF = myCDFExport.cdfspec4;
      deleting = (myCDFExport.overwrite == 0 ? false : true);

      if (deleting) {
        File cdfFile1 = new File(destCDF+".cdf");
        if (cdfFile1.exists()) cdfFile1.delete();
	File cdfFile2 = new File(destCDF+".CDF");
	if (cdfFile2.exists()) cdfFile2.delete();
      }
   }

   public void run() {

      try {
	cdf = CDF.open(destCDF, READONLYoff);
	try {
	  if (deleting) {
	    cdf.delete();
	  }
	  else {
	    cdf.close();
	    myCDFExport.info.setText("Error! CDF: "+ destCDF+ " already exists");
	    Toolkit.getDefaultToolkit().beep();
	    return;
	  }
	} catch (CDFException ex) {
	    if (cdf != null) cdf.close(); 
	    myCDFExport.info.setText("Error! CDF: "+ destCDF+ " "+ex.toString());
	    Toolkit.getDefaultToolkit().beep();
	    return;
	}
      } catch (CDFException ex) { }
      cdf = null;
      try {
	CDF.setFileBackward(myCDFExport.backwardFlag);
        cdf  = CDF.create(destCDF);
      } catch (CDFException ex) {
	  myCDFExport.info.setText("Error: "+ ex.toString());
	  Toolkit.getDefaultToolkit().beep();
	  return;
      }

      myCDFExport.info.setText("Exporting starts...\n");
      myCDFExport.info.append("from: "+ sourceCDF.getName()+"\n");
      myCDFExport.info.append("  to: "+ destCDF+"\n");

      try {

        /*********************************/
        /*  Set miscelleneous settings.  */
        /*********************************/

        cdf.setFormat(myCDFExport.format);
      } catch (CDFException ex) {}

      if (myCDFExport.compressionType != -1) {
        try {
          cdf.setCompression((long) myCDFExport.compressionType, 
	  	   	     new long[] {myCDFExport.compressionLevel});
        } catch (CDFException ex) {}
      } else {
        try {
          cdf.setCompression(sourceCDF.getCompressionType(),
                             sourceCDF.getCompressionParms());
        } catch (CDFException ex) {}
      }

      try {
	if (myCDFExport.majority == 0) // source majority
	  cdf.setMajority(sourceCDF.getMajority());
	else
          cdf.setMajority(myCDFExport.majority);
        cdf.setEncoding(sourceCDF.getEncoding());
	if (myCDFExport.checksum != NONE_CHECKSUM) 
          cdf.setChecksum(myCDFExport.checksum);
      } catch (CDFException ex) { 
	System.err.println("Error...1 "+ex);
      }

      try {
        cdf.selectNegtoPosfp0(sourceCDF.confirmNegtoPosfp0());
      } catch (CDFException ex) {}

        /*******************************************/
        /*  Create global and variable attributes  */
        /*******************************************/

      try {
	Vector globalAttributes = sourceCDF.getGlobalAttributes();
	int noentries = 0;
	for (Enumeration e = globalAttributes.elements(); e.hasMoreElements(); ) {
	   Vector entries = ((Attribute)e.nextElement()).getEntries();
	   if (entries != null) noentries += entries.size();
	}

	variableAttributes = sourceCDF.getVariableAttributes();

	if (variableAttributes != null) noentries += variableAttributes.size();

	int norecords = 0;
        for (Enumeration e = myCDFExport.vars.elements(); e.hasMoreElements(); ) {
           variable = (Variable)e.nextElement();
           if (variable.getNumWrittenRecords() > 0) {
              irec = (int) variable.getMaxWrittenRecord();
	      norecords += irec;
	   }
	}

	totalItems = noentries + norecords;
	progressPanel = new BuildProgressPanel(exportCreateCDF, totalItems);

	for (Enumeration e = globalAttributes.elements(); e.hasMoreElements(); ) {
	   attribute = (Attribute)e.nextElement();
           newAttribute  = Attribute.create(cdf, attribute.getName(), GLOBAL_SCOPE);
	   Vector entries = attribute.getEntries();
	   Entry entry, newEntry;
	   for (Enumeration ee = entries.elements(); ee.hasMoreElements(); ) {
	      entry = (Entry)ee.nextElement();
	      if (entry != null) newEntry = Entry.create(newAttribute, entry.getID(), 
					      entry.getDataType(), entry.getData());
	   }
	   if (entries != null) currentProgressValue += entries.size();   
	}

	new UpdateProgress(exportCreateCDF, currentProgressValue).start();
      } catch (CDFException ex) {}

      try {
        for (Enumeration e = variableAttributes.elements(); e.hasMoreElements(); ) {
	   attribute = (Attribute)e.nextElement();
	   if (attribute != null) 
             newAttribute = Attribute.create(cdf, attribute.getName(), VARIABLE_SCOPE);
        }

	if (variableAttributes != null) currentProgressValue += variableAttributes.size();
	new UpdateProgress(exportCreateCDF, currentProgressValue).start();
      } catch (CDFException ex) {}

        /**********************/
        /*  Create variables  */
        /**********************/

      try {
	for (Enumeration e = myCDFExport.vars.elements(); e.hasMoreElements(); ) {
	   variable = (Variable)e.nextElement();
//System.err.println("var = "+variable);
	   int ind = ((Integer)exportCDFTable.myHash.get(variable.getName())).intValue(); 
	   irec = -1;
	   try {
	     if (variable.getNumWrittenRecords() > 0) 
		irec = (int) variable.getMaxWrittenRecord();
	   } catch (CDFException ex) {}

	   if (((Boolean) ((Object[][])exportCDFTable.getDataObject())[ind][5]).booleanValue()) {
	     
		boolean toAll; // Check whether its data is going to be filtered.
		if (exportCDFTable.numColumns2 > 0) toAll = false;
		else toAll = true;
/*
		for (int a1 = 1; a1 < exportCDFTable.numColumns2; a1++)
		  if (exportCDFTable.updateTable[ind][a1]) {
		    toAll = false;
		    break;
		}
*/
/*		newVariable = variable.copy(cdf, variable.getName()); */
		long dt, ne, nd, rv;
		long[] ds, dv;
		try {
		    dt = variable.getDataType();
		    ne = variable.getNumElements();
		    nd = variable.getNumDims();
		    ds = variable.getDimSizes();
		    rv = ((variable.getRecVariance())?VARY:NOVARY);
		    dv = variable.getDimVariances();
		    if (nd == 0) {
		      ds = new long[] {1};
		      dv = new long[] {VARY};
		    }
		    newVariable = Variable.create(cdf, variable.getName(),
						  dt, ne, nd, ds, rv, dv);
                } catch (CDFException ex) {
                  System.err.println("error...00 gettting variable info:"+ex);
                }

		try {
		   long bf = variable.getBlockingFactor();
		   newVariable.setBlockingFactor(bf);
		} catch (CDFException ex) {
		  System.err.println("error...1 setBlockingFactor "+ex);
		}

		padValue = false;
		try {
		   if (variable.checkPadValueExistence()) { 
                     Object pv = variable.getPadValue();
                     if (pv != null) {
		       newVariable.setPadValue(pv);
		       padValue = true;
		     }
		   }
                } catch (CDFException ex) {
		  System.err.println("error...2 setPadValue "+ex);
		}

                try {
                  long ct = variable.getCompressionType();
                  long[] cp = variable.getCompressionParms();
                  newVariable.setCompression(ct, cp);
		  compressed = true;
                } catch (CDFException ex) {
		  compressed = false;
		  System.err.println("error...3 setCompression "+ex);
		}

                try {
                  long sp = variable.getSparseRecords();
                  newVariable.setSparseRecords(sp);
                } catch (CDFException ex) {
                  System.err.println("error...3a setSparseRecords "+ex);
                }

		if (!toAll) {
		  Attribute newAttr = null;
		  Attribute oldAttr = null;
		  for (int a1 = 1; a1 < exportCDFTable.numColumns2; a1++) {
//		    if (exportCDFTable.updateTable[ind][a1]) {
		      Object tmp =  ((Object[][])exportCDFTable.getFilterObject())[ind][a1];
		      try {
		        newAttr = cdf.getAttribute(exportCDFTable.columnNames2[a1]);
		        oldAttr = sourceCDF.getAttribute(exportCDFTable.columnNames2[a1]);
		        if (tmp != null || tmp.toString().trim().length() != 0) {
			  newAttr.deleteEntry(newVariable);
			  long dataType = oldAttr.getEntry(variable).getDataType();
			  Object entry = null;
			  StringTokenizer st = new StringTokenizer((String) tmp, ",");
			  int lenx = st.countTokens();
			  if (lenx == -1) entry = null;
			  else entry = CDFToolUtils.parseContents((String)tmp, dataType);
			  if (entry != null) 
			    Entry.create(newAttr, newVariable.getID(), dataType, entry);
			}
		      } catch (CDFException es) {
			System.err.println("error...4 create attribute entry "+es); 
		      }
//		    }
		  }
		} else {
	          // Copy the metadata
	          Vector attributes = variable.getMyCDF().getAttributes();
	          Attribute curAttr;
	          Entry curEntry;
	          for (Enumeration ea=attributes.elements(); ea.hasMoreElements() ;) {
	             curAttr = (Attribute)ea.nextElement();
	             if (curAttr.getScope() == VARIABLE_SCOPE)
	             try {
		          curEntry = curAttr.getEntry(variable.getID());
                          Attribute destAttr;
                          if (cdf.getAttributeID(curAttr.getName()) == -1L)
                            destAttr =     
                              Attribute.create(cdf, curAttr.getName(),
                                               VARIABLE_SCOPE);
                          else              
                            destAttr = cdf.getAttribute(curAttr.getName());
                          Entry.create(destAttr, newVariable.getID(),
                                       curEntry.getDataType(), curEntry.getData());
	             } catch (CDFException ce) {
	             }
	          }   
		}

		if (irec > -1) {
		  if (!padValue && !compressed)
		    newVariable.allocateRecords((long) irec+1);
		  loadRecords(newVariable, variable);
/*
                  try {
                    long ct = variable.getCompressionType();
                    long[] cp = variable.getCompressionParms();
                    newVariable.setCompression(ct, cp);

                  } catch (CDFException ex) {
		    System.err.println("error...5 setCompression "+ex);
		  }
*/
		}
	   }
	   currentProgressValue += (irec+1);
	   new UpdateProgress(exportCreateCDF, currentProgressValue).start();
	}

	new CleanProgress().start();
	myCDFExport.info.append("\n\nexporting is done");
        cdf.close();
	cdf = null;

      } catch (Exception ex) {
        System.out.println("A bad thing happened on the way to the CDF.");
        ex.printStackTrace();
      }
    }

/**
  * Copy the records from a source CDF's variable into the destination CDF 
  */

    private void loadRecords(Variable newVar, Variable oldVar) {

	long dataType = oldVar.getDataType();

	if ((myCDFExport.getFiltering() == 0) ||
	    (myCDFExport.getFiltering() == 1 && 
	     myCDFExport.getValidMin() == 0 && 
	     myCDFExport.getValidMax() == 0 &&
	     myCDFExport.getFillVal() == 0)) {
	  // no filtering applied -- copy all records
	  try {
	    oldVar.copyDataRecords(newVar);
	  } catch (CDFException ex) {
	    System.err.println("error copying data records");
	    return;
	  }
	} else {
	  int ind = ((Integer)exportCDFTable.myHash.get(oldVar.getName())).intValue();
	  int ifil = 0;
	  boolean changed = false;
	  if (myCDFExport.getValidMin() == 1) {
	    ifil ++;
	    newMin = ((Object[][])exportCDFTable.getFilterObject())[ind][ifil];
	    changed = true;
	    if (newMin != null && ((String) newMin).trim().length() > 0) {
              StringTokenizer st = new StringTokenizer((String) newMin, ",");
	      minLen = st.countTokens();
	      if (minLen == -1) minObj = null;
	      else minObj = CDFToolUtils.parseContents((String) newMin, dataType);
	    } else minObj = null;
          } 

	  if (myCDFExport.getValidMax() == 1) {
	    ifil ++;
            newMax = ((Object[][])exportCDFTable.getFilterObject())[ind][ifil];
            changed = true;
	    if (newMax != null && ((String) newMax).trim().length() > 0) {
	      StringTokenizer st = new StringTokenizer((String) newMax, ",");
	      maxLen = st.countTokens();
	      if (maxLen == -1) maxObj = null;
	      else maxObj = CDFToolUtils.parseContents((String) newMax, dataType);
	    } else maxObj = null;
          }

	  if (myCDFExport.getFillVal() == 1) {
	    ifil ++;
            newFil = ((Object[][])exportCDFTable.getFilterObject())[ind][ifil];
	    if (newFil != null && ((String) newFil).trim().length() > 0) {
              StringTokenizer st = new StringTokenizer((String) newFil, ",");
              filLen = st.countTokens();
              if (filLen == -1) filObj = null;
              else filObj = CDFToolUtils.parseContents((String) newFil, dataType);
              changed = true;
	    } else filObj = null;
          } else {
		try { 
		  Object obj = oldVar.getEntryData("FILLVAL");
		  if (obj != null) {
		    String tmp = obj.toString();
		    StringTokenizer st = new StringTokenizer(tmp, ",");
		    filLen = st.countTokens();
		    if (filLen == -1) filObj = null;
		    else filObj = CDFToolUtils.parseContents(tmp, dataType);
		  } else filObj = null;
		} catch (CDFException ex) { filObj = null; }
	  }

	  if (!changed) {
	    try {
	      oldVar.copyDataRecords(newVar);
	    } catch (CDFException ex) {
	      System.err.println("error copying data records");
	      return;
	    }
	  } else {
	    Object record;
	    for (int vin = 0; vin <= irec; vin++) {
		try {
		  record = oldVar.getRecord((long) vin);
		  record = filterData(record, newVar);
		  newVar.putRecord((long) vin, record);
		} catch (CDFException ex) {
		  System.err.println("error read/write one record");
		  return;
		}
	    }
	  }
	}

    }

    private Object filterData(Object _dataArray, Variable _myVar) {

        long dataType = _myVar.getDataType();
        int nDims = (int)_myVar.getNumDims();
        long[] dimSizes = _myVar.getDimSizes();
	boolean goon = true;

        /////////////////////////////////////////////////////////////
        //                                                         //
        //                    For <= 1D Array                      //
        //                                                         //
        /////////////////////////////////////////////////////////////

        if (nDims <= 1) {
            if (nDims == 0) {
		goon = true;
		if (dataType == CDF_CHAR || dataType == CDF_UCHAR) {
		} else if (dataType == CDF_BYTE || dataType == CDF_INT1) {
		    byte aByte = ((Byte)_dataArray).byteValue();
                    if (minObj != null) {
			if (aByte < ((byte[])minObj)[0]) {
			  if (filObj != null) _dataArray = new Byte(((byte[])filObj)[0]);
			  else _dataArray = new Byte((byte)0);
			}
		    }
                    if (maxObj != null) {
                        if (aByte > ((byte[])maxObj)[0]) {
			  if (filObj != null) _dataArray = new Byte(((byte[])filObj)[0]);
                          else _dataArray = new Byte((byte)0);
                        }
                    }
		} else if (dataType == CDF_INT2 || dataType == CDF_UINT1) {
                    short ashort = ((Short)_dataArray).shortValue();
                    short afill = 0;
                    short amax = 0;
                    short amin = 0;
                    if (filObj != null) afill = ((short[])filObj)[0];
                    if (minObj != null) amin = ((short[])minObj)[0];
                    if (maxObj != null) amax = ((short[])maxObj)[0];
                    if (dataType == CDF_UINT1) {
                      if (afill < 0) afill -= (short) 2*Byte.MIN_VALUE;
                      if (ashort < 0) ashort -= (short) 2*Byte.MIN_VALUE;
                      if (amin < 0) amin -= (short) 2*Byte.MIN_VALUE;
                      if (amax < 0) amax -= (short) 2*Byte.MIN_VALUE;
                    }

                    if (minObj != null) {
                        if (ashort < amin) {
			  goon = false;
			  if (filObj != null) _dataArray = new Short(afill);
                          else _dataArray = new Short((short)0);
                        }
                    }
                    if (goon && maxObj != null) {
                        if (ashort > amax) {
			  if (filObj != null) _dataArray = new Short(afill);
                          else _dataArray = new Short((short)0);
                        }
                    }
		} else if (dataType == CDF_INT4 || dataType == CDF_UINT2) {
                    int aint = ((Integer)_dataArray).intValue();
                    int afill = 0;
                    int amax = 0;
                    int amin = 0;
                    if (filObj != null) afill = ((int[])filObj)[0];
                    if (minObj != null) amin = ((int[])minObj)[0];
                    if (maxObj != null) amax = ((int[])maxObj)[0];
                    if (dataType == CDF_UINT2) {
                      if (afill < 0) afill -= (int) 2*Short.MIN_VALUE;
                      if (aint < 0) aint -= (int) 2*Short.MIN_VALUE;
                      if (amin < 0) amin -= (int) 2*Short.MIN_VALUE;
                      if (amax < 0) amax -= (int) 2*Short.MIN_VALUE;
                    }

                    if (minObj != null) {
                        if (aint < amin) {
                          goon = false;
			  if (filObj != null) _dataArray = new Integer(afill);
                          else _dataArray = new Integer(0);
                        }
                    }
                    if (goon && maxObj != null) {
                        if (aint > amax) {
			  if (filObj != null) _dataArray = new Integer(afill);
                          else _dataArray = new Integer(0);
                        }
                    }
		} else if (dataType == CDF_UINT4 || dataType == CDF_INT8 ||
                           dataType == CDF_TIME_TT2000) {
                    long along = ((Long)_dataArray).longValue();
                    long afill = 0L;
                    long amax = 0L;
                    long amin = 0L;
                    if (filObj != null) afill = ((long[])filObj)[0];
                    if (minObj != null) amin = ((long[])minObj)[0];
                    if (maxObj != null) amax = ((long[])maxObj)[0];
                    if (dataType == CDF_UINT4) {
                      if (afill < 0) afill -= (long) 2*Integer.MIN_VALUE;
                      if (along < 0) along -= (long) 2*Integer.MIN_VALUE;
                      if (amin < 0) amin -= (long) 2*Integer.MIN_VALUE;
                      if (amax < 0) amax -= (long) 2*Integer.MIN_VALUE;
                    }
                    if (minObj != null) {
                        if (along < amin) {
                          goon = false;
			  if (filObj != null) _dataArray = new Long(afill);
                          else _dataArray = new Long(0L);
                        }
                    }
                    if (goon && maxObj != null) {
                        if (along > amax) {
			  if (filObj != null) _dataArray = new Long(afill);
                          else _dataArray = new Long(0L);
                        }
                    }
		} else if (dataType == CDF_REAL4 || dataType == CDF_FLOAT) {
                    float aFloat = ((Float)_dataArray).floatValue();
                    if (minObj != null) {
                        if (aFloat < ((float[])minObj)[0]) {
                          goon = false;
                          if (filObj != null) _dataArray = new Float(((float[])filObj)[0]);
			  else _dataArray = new Float(0.0F);
			}
                    }
                    if (goon && maxObj != null) {
                        if (aFloat > ((float[])maxObj)[0]) {
                          if (filObj != null) _dataArray = new Float(((float[])filObj)[0]);                   
                          else _dataArray = new Float(0.0F);
                        }
                    }
		} else if (dataType == CDF_REAL8 || dataType == CDF_DOUBLE || 
			   dataType == CDF_EPOCH) {
                    double aDouble = ((Double)_dataArray).doubleValue();
                    if (minObj != null) {
                        if (aDouble < ((double[])minObj)[0]) {
                          goon = false;
                          if (filObj != null) _dataArray = new Double(((double[])filObj)[0]);                   
                          else _dataArray = new Double(0.0);
                        }
                    }
                    if (goon && maxObj != null) {
                        if (aDouble > ((double[])maxObj)[0]) {
                          if (filObj != null) _dataArray = new Double(((double[])filObj)[0]);                   
                          else _dataArray = new Double(0.0);
                        }
                    }
                } else if (dataType == CDF_EPOCH16) {
                    double[] aDouble = new double[2];
		    aDouble[0] = ((double[])_dataArray)[0];
		    aDouble[1] = ((double[])_dataArray)[1];
                    if (minObj != null) {
                        if (aDouble[0] < ((double[])minObj)[0] ||
			    (aDouble[0] == ((double[])minObj)[0] &&
			     aDouble[1] < ((double[])minObj)[1])) {
                          goon = false;
                          if (filObj != null) {
			    _dataArray = new double[2];
			    ((double[])_dataArray)[0] = ((double[])filObj)[0];
			    ((double[])_dataArray)[1] = ((double[])filObj)[1];
			    
			  } else 
			    _dataArray = new double[] {0.0, 0.0};
                        }
                    }
                    if (goon && maxObj != null) {
                        if (aDouble[0] > ((double[])maxObj)[0] ||
			    (aDouble[0] == ((double[])maxObj)[0] &&
			     aDouble[1] > ((double[])maxObj)[1])) {
                          if (filObj != null) {
			    _dataArray = new double[2];
			    ((double[])_dataArray)[0] = ((double[])filObj)[0];
			    ((double[])_dataArray)[1] = ((double[])filObj)[1];
			  } else
                            _dataArray = new double[] {0.0, 0.0};
                        }
                    }
		}
            } else { // for 1-D array
                if (dataType == CDF_CHAR || dataType == CDF_UCHAR) {
		} else if (dataType == CDF_BYTE || dataType == CDF_INT1) {
		    byte abyte = 0, tmpMin = 0, tmpMax = 0, tmpFil = 0;
		    if (minObj != null && minLen == 1)  
			tmpMin = ((byte[])minObj)[0];
                    if (maxObj != null && maxLen == 1)  
                        tmpMax = ((byte[])maxObj)[0];
                    if (filObj != null)  
                        tmpFil = ((byte[])filObj)[0];

                    for (int j = 0; j < (int) dimSizes[0]; j++) {
                        goon = true;
			abyte = ((byte [])_dataArray)[j];
			if (minObj != null) {
                          if (minLen == 1) {
                            if (abyte < tmpMin) {
                              goon = false;
                              if (filObj != null) ((byte [])_dataArray)[j] = tmpFil;
                              else ((byte [])_dataArray)[j] = 0;
                            }
                          } else {
			    if (((byte [])minObj).length > j) {
                              if (abyte < ((byte [])minObj)[j]) {
                                goon = false;
                                if (filObj != null) ((byte [])_dataArray)[j] = tmpFil;
                                else ((byte [])_dataArray)[j] = 0;
			      }
                            }
                          }
			}
                        if (goon && maxObj != null) {
                          if (maxLen == 1) {
                            if (abyte > tmpMax) {
                              if (filObj != null) ((byte [])_dataArray)[j] = tmpFil;
                              else ((byte [])_dataArray)[j] = 0;
                            }
                          } else {
			    if (((byte [])maxObj).length > j) {
                              if (abyte > ((byte [])maxObj)[j]) {
                                if (filObj != null) ((byte [])_dataArray)[j] = tmpFil;
                                else ((byte [])_dataArray)[j] = 0;
			      }
                            }
                          }
                        }
                    }
		} else if (dataType == CDF_INT2 || dataType == CDF_UINT1) {
                    short ashort = 0;
                    short tmpMin = 0, tmpMax = 0, tmpFil = 0;
                    if (minObj != null) tmpMin = ((short[])minObj)[0];
                    if (maxObj != null) tmpMax = ((short[])maxObj)[0];
                    if (filObj != null) tmpFil = ((short[])filObj)[0];
                    if (dataType == CDF_UINT1) {
                      if (tmpMin < 0) tmpMin -= (short) 2*Byte.MIN_VALUE;
                      if (tmpMax < 0) tmpMax -= (short) 2*Byte.MIN_VALUE;
                      if (tmpFil < 0) tmpFil -= (short) 2*Byte.MIN_VALUE;
                    }

                    for (int j = 0; j < (int) dimSizes[0]; j++) {
                        goon = true;
			ashort = ((short [])_dataArray)[j];
			if (dataType == CDF_UINT1 && ashort < 0) ashort -= (short) 2*Byte.MIN_VALUE;

                        if (minObj != null) {
                            if (minLen == 1) {
                              if (ashort < tmpMin) {
                                goon = false;                          
                                if (filObj != null) ((short [])_dataArray)[j] = tmpFil;
                                else ((short [])_dataArray)[j] = 0;
                              }
                            } else {
			      if (((short [])minObj).length > j) {
                                short avalue = ((short [])minObj)[j];
                                if (dataType == CDF_UINT1 && avalue < 0) avalue -= (short) 2*Byte.MIN_VALUE;
                                if (ashort < avalue) {
                                  goon = false;                          
                                  if (filObj != null) ((short [])_dataArray)[j] = tmpFil;
                                  else ((short [])_dataArray)[j] = 0;
				}
                              }
                            }
                        }
                        if (goon && maxObj != null) {
                            if (maxLen == 1) {
                              if (ashort > tmpMax) {
                                if (filObj != null) ((short [])_dataArray)[j] = tmpFil;
                                else ((short [])_dataArray)[j] = 0;
                              }
                            } else {
			      if (((short [])maxObj).length > j) {
                                short avalue = ((short [])maxObj)[j];
                                if (dataType == CDF_UINT1 && avalue < 0) avalue -= (short) 2*Byte.MIN_VALUE;
                                if (ashort > avalue) {
                                  if (filObj != null) ((short [])_dataArray)[j] = tmpFil;
                                  else ((short [])_dataArray)[j] = 0;
				}
                              }
                            }
                        }

                    }
		} else if (dataType == CDF_INT4 || dataType == CDF_UINT2) {
                    int aint = 0;
                    int tmpMin = 0, tmpMax = 0, tmpFil = 0;
                    if (minObj != null) tmpMin = ((int[])minObj)[0];
                    if (maxObj != null) tmpMax = ((int[])maxObj)[0];
                    if (filObj != null) tmpFil = ((int[])filObj)[0];
                    if (dataType == CDF_UINT2) {
                      if (tmpMin < 0) tmpMin -= (int) 2*Short.MIN_VALUE;
                      if (tmpMax < 0) tmpMax -= (int) 2*Short.MIN_VALUE;
                      if (tmpFil < 0) tmpFil -= (int) 2*Short.MIN_VALUE;
                    }

                    for (int j = 0; j < (int) dimSizes[0]; j++) {
                        goon = true;
			aint = ((int [])_dataArray)[j];
			if (dataType == CDF_UINT2 && aint < 0) aint -= (int) 2*Short.MIN_VALUE;

                        if (minObj != null) {
                            if (minLen == 1) {
                              if (aint < tmpMin) {
                                goon = false;                          
                                if (filObj != null) ((int [])_dataArray)[j] = tmpFil;
                                else ((int [])_dataArray)[j] = 0;
                              }
                            } else {
			      if (((int [])minObj).length > j) {
                                int avalue = ((int [])minObj)[j];
                                if (dataType == CDF_UINT2 && avalue < 0) avalue -= (int) 2*Short.MIN_VALUE;
                                if (aint < avalue) {
                                  goon = false;                          
                                  if (filObj != null) ((int [])_dataArray)[j] = tmpFil;
                                  else ((int [])_dataArray)[j] = 0;
				}
                              }
                            }
                        }
                        if (goon && maxObj != null) {
                            if (maxLen == 1) {
                              if (aint > tmpMax) {
                                if (filObj != null) ((int [])_dataArray)[j] = tmpFil;
                                else ((int [])_dataArray)[j] = 0;
                              }
                            } else {
			      if (((int [])maxObj).length > j) {
                                int avalue = ((int [])maxObj)[j];
                                if (dataType == CDF_UINT2 && avalue < 0) avalue -= (int) 2*Short.MIN_VALUE;
                                if (aint > avalue) {
                                  if (filObj != null) ((int [])_dataArray)[j] = tmpFil;
                                  else ((int [])_dataArray)[j] = 0;
				}
                              }
                            }
                        }
                    }
		} else if (dataType == CDF_UINT4 || dataType == CDF_INT8 ||
                           dataType == CDF_TIME_TT2000) {
                    long along = 0;
                    long tmpMin = 0L, tmpMax = 0L, tmpFil = 0L;
                    if (minObj != null) tmpMin = ((long[])minObj)[0];
                    if (maxObj != null) tmpMax = ((long[])maxObj)[0];
                    if (filObj != null) tmpFil = ((long[])filObj)[0];
                    if (dataType == CDF_UINT4) {
                      if (tmpMin < 0) tmpMin -= (long) 2*Integer.MIN_VALUE;
                      if (tmpMax < 0) tmpMax -= (long) 2*Integer.MIN_VALUE;
                      if (tmpFil < 0) tmpFil -= (long) 2*Integer.MIN_VALUE;
                    }
                    for (int j = 0; j < (int) dimSizes[0]; j++) {
                      goon = true;
                      along = ((long [])_dataArray)[j];
                      if (dataType == CDF_UINT4)
                        if (along < 0) along -= (long) 2*Integer.MIN_VALUE;
                      if (minObj != null) {
                          if (minLen == 1) {
                            if (along < tmpMin) {
                              goon = false;                          
                              if (filObj != null) ((long [])_dataArray)[j] = tmpFil;
                              else ((long [])_dataArray)[j] = 0;
                            }
                          } else {
			    if (((long [])minObj).length > j) {
                              long avalue = ((long [])minObj)[j];
                              if (dataType == CDF_UINT4)
                                if (avalue < 0) avalue -= (long) 2*Integer.MIN_VALUE;
                              if (along < avalue) {
                                goon = false;                          
                                if (filObj != null) ((long [])_dataArray)[j] = tmpFil;
                                else ((long [])_dataArray)[j] = 0;
			      }
                            }
                          }
                      } 
                      if (goon && maxObj != null) {
                          if (maxLen == 1) {
                            if (along > tmpMax) {
                              if (filObj != null) ((long [])_dataArray)[j] = tmpFil;
                              else ((long [])_dataArray)[j] = 0;
                            }
                          } else {
			    if (((long [])maxObj).length > j) {
                              long avalue = ((long [])maxObj)[j];
                              if (dataType == CDF_UINT4)
                                if (avalue < 0) avalue -= (long) 2*Integer.MIN_VALUE;
                              if (along > avalue) {
                                if (filObj != null) ((long [])_dataArray)[j] = tmpFil;
                                else ((long [])_dataArray)[j] = 0;
			      }
                            }
                          }
                      }
                    }
		} else if (dataType == CDF_REAL4 || dataType == CDF_FLOAT) {
		    float tmpMin = 0.0F, tmpMax = 0.0F, tmpFil = 0.0F;
                    if (minObj != null && minLen == 1)
                        tmpMin = ((float[])minObj)[0];
                    if (maxObj != null && maxLen == 1)
                        tmpMax = ((float[])maxObj)[0];
                    if (filObj != null)
                        tmpFil = ((float[])filObj)[0];

                    for (int j = 0; j < (int) dimSizes[0]; j++) {
                        goon = true;
			float afloat = ((float [])_dataArray)[j];
                        if (minObj != null) {
                          if (minLen == 1) {
                            if (afloat < tmpMin) {
                              goon = false;                          
                              if (filObj != null) ((float [])_dataArray)[j] = tmpFil;
                              else ((float [])_dataArray)[j] = 0.0F;
                            }
                          } else {
			    if (((float [])minObj).length > j) {
                              if (afloat < ((float [])minObj)[j]) {
                                goon = false;                          
                                if (filObj != null) ((float [])_dataArray)[j] = tmpFil;
                                else ((float [])_dataArray)[j] = 0.0F;
			      }
                            }
                          }
			}
                        if (goon && maxObj != null) {
                          if (maxLen == 1) {
                            if (afloat > tmpMax) {
                              if (filObj != null) ((float [])_dataArray)[j] = tmpFil;
                              else ((float [])_dataArray)[j] = 0.0F;
                            }
                          } else {
			    if (((float [])maxObj).length > j) {
                              if (afloat > ((float [])maxObj)[j]) {
                                if (filObj != null) ((float [])_dataArray)[j] = tmpFil;
                                else ((float [])_dataArray)[j] = 0.0F;
			      }
                            }
			  }
                        }
                    }
		} else if (dataType == CDF_REAL8 || dataType == CDF_DOUBLE ||
			   dataType == CDF_EPOCH) {
		    double tmpMin = 0.0D, tmpMax = 0.0D, tmpFil = 0.0D;
                    if (minObj != null && minLen == 1)
                        tmpMin = ((double[])minObj)[0];
                    if (maxObj != null && maxLen == 1)
                        tmpMax = ((double[])maxObj)[0];
                    if (filObj != null)
                        tmpFil = ((double[])filObj)[0];

                    for (int j = 0; j < (int) dimSizes[0]; j++) {
			goon = true;
			double adouble = ((double [])_dataArray)[j];
                        if (minObj != null) {
                          if (minLen == 1) {
                            if (adouble < tmpMin) {
                              goon = false;                          
                              if (filObj != null) ((double [])_dataArray)[j] = tmpFil;
                              else ((double [])_dataArray)[j] = 0.0;
                            }
                          } else {
			    if (((double [])minObj).length > j) {
                              if (adouble < ((double [])minObj)[j]) {
                                goon = false;                          
                                if (filObj != null) ((double [])_dataArray)[j] = tmpFil;
                                else ((double [])_dataArray)[j] = 0.0;
			      }
                            }
                          }
                        }
                        if (goon && maxObj != null) {
                          if (maxLen == 1) {
                            if (adouble > tmpMax) {
                              if (filObj != null) ((double [])_dataArray)[j] = tmpFil;
                              else ((double [])_dataArray)[j] = 0.0;
                            }
                          } else {
			    if (((double [])maxObj).length > j) {
                              if (adouble > ((double [])maxObj)[j]) {
                                if (filObj != null) ((double [])_dataArray)[j] = tmpFil;
                                else ((double [])_dataArray)[j] = 0.0;
			      }
                            }
                          }
                        }
                    }
                } else if (dataType == CDF_EPOCH16) {
                    double[] tmpMin = new double[] {0.0D, 0.0D}, 
			     tmpMax = new double[] {0.0D, 0.0D},
			     tmpFil = new double[] {0.0D, 0.0D};
                    if (minObj != null && minLen == 1) {
                        tmpMin[0] = ((double[])minObj)[0];
			tmpMin[1] = ((double[])minObj)[1];
                    }
		    if (maxObj != null && maxLen == 1) {
                        tmpMax[0] = ((double[])maxObj)[0];
			tmpMax[1] = ((double[])maxObj)[1];
                    }
		    if (filObj != null) {
                        tmpFil[0] = ((double[])filObj)[0];
			tmpFil[1] = ((double[])filObj)[1];
		    }

                    for (int j = 0; j < (int) dimSizes[0]; j++) {
                        goon = true;
                        double[] adouble = new double[2];
			adouble[0] = ((double [])_dataArray)[2*j];
			adouble[1] = ((double [])_dataArray)[2*j+1];
                        if (minObj != null) {
                          if (minLen == 1) {
                            if (adouble[0] < tmpMin[0] ||
				(adouble[0] == tmpMin[0] &&
				 adouble[1] < tmpMin[1] )) {
                              goon = false;
                              if (filObj != null) {
				((double [])_dataArray)[2*j] = tmpFil[0];
				((double [])_dataArray)[2*j+1] = tmpFil[1];
			      } else {
                                ((double [])_dataArray)[2*j] = 0.0;
				((double [])_dataArray)[2*j+1] = 0.0;
			      }
                            }
                          } else {
                            if (((double [])minObj).length > j) { /* ????? */
                              if (adouble[0] < ((double [])minObj)[2*j] ||
				  (adouble[0] == ((double [])minObj)[2*j] &&
				   adouble[1] < ((double [])minObj)[2*j+1] )) {
                                goon = false;
                                if (filObj != null) {
				  ((double [])_dataArray)[2*j] = tmpFil[0];
				  ((double [])_dataArray)[2*j+1] = tmpFil[0];
				} else {
                                  ((double [])_dataArray)[2*j] = 0.0;
				  ((double [])_dataArray)[2*j+1] = 0.0;
				}
                              }
                            }
                          }
                        }
                        if (goon && maxObj != null) {
                          if (maxLen == 1) {
                            if (adouble[0] > tmpMax[0] ||
				(adouble[0] == tmpMax[0] &&
				 adouble[1] > tmpMax[1] )) {
                              if (filObj != null) {
				((double [])_dataArray)[2*j] = tmpFil[0];
				((double [])_dataArray)[2*j+1] = tmpFil[1];
			      } else {
                                ((double [])_dataArray)[2*j] = 0.0;
				((double [])_dataArray)[2*j+1] = 0.0;
			      }
                            }
                          } else {
                            if (((double [])maxObj).length > j) { /* ????? */
                              if (adouble[0] > ((double [])maxObj)[2*j] ||
				  (adouble[0] == ((double [])maxObj)[2*j] &&
				   adouble[1] > ((double [])maxObj)[2*j+1] )) {
                                if (filObj != null) {
				  ((double [])_dataArray)[2*j] = tmpFil[0];
				  ((double [])_dataArray)[2*j+1] = tmpFil[1];
                                } else {
				  ((double [])_dataArray)[2*j] = 0.0;
				  ((double [])_dataArray)[2*j+1] = 0.0;
				}
                              }
                            }
                          }
                        }
                    }
		}
	    }

        ////////////////////////////////////////////////////////
        //                                                    //
        //              Multidimensional Arrays               //
        //                                                    //
        ////////////////////////////////////////////////////////

        } else {
            /*
             * Setup the subArrays array
             * cIndex is the holds the index for the current subarray
             * boundary is the # of values in the subarray
             */
            Object aRow = null;
            Object [] subArrays = new Object[(int)nDims-1];
            int [] cIndex   = new int[(int)nDims-1];
            long [] boundary = new long[(int)nDims-1];

            subArrays[0] = _dataArray;
            cIndex[0] = 0;
	    boundary[0] = product(dimSizes, 0, (int)nDims);

            for (int i = 1; i < (int)nDims-1; i++) {
                subArrays[i] = Array.get(subArrays[i-1], 0);
                boundary[i] = product(dimSizes,i,(int)nDims);
                cIndex[i] = 0;
            }

            int n = 0; // The current element in the _data
            Object cObject = _dataArray;  // A temp object to hold a subarray
            boolean boundaryCrossed;

            while (n < boundary[0]) {
                // Get the correct 2D subarray to print
                if (n!=0) {
                    for (int i = 0; i < (int)nDims-1; i++) {
                        boundaryCrossed = ((n % boundary[i]) == 0);
                        if (boundaryCrossed) {
                            // Get the next sub array
                            cIndex[i]++;
                            cObject = Array.get(cObject, cIndex[i]);
                            subArrays[i] = cObject;

                            // Get the first element of each
                            // subsequent subarray
                            for (int j=i+1;j<(int)nDims-1;j++) {
                                cIndex[j] = 0;
                                subArrays[j] = Array.get(subArrays[j-1],cIndex[j]);
                            }
                            break;

                        } else {
                            cObject = subArrays[i];
                        }
                    }
                }

                // Fill the correct elements of _data
                if (dataType == CDF_CHAR || dataType == CDF_UCHAR) {
		} else if (dataType == CDF_BYTE || dataType == CDF_INT1) {
		    byte tmpMin = 0, tmpMax = 0, tmpFil = 0;
		    if (minObj != null && minLen == 1) 
			tmpMin = ((byte[])minObj)[0];
		    if (maxObj != null && maxLen == 1) 
			tmpMax = ((byte[])maxObj)[0];
		    if (filObj != null)
			tmpFil = ((byte[])filObj)[0];

		    for (int i = 0; i < (int) dimSizes[(int)nDims-2]; i++) {
                        aRow = (byte [])Array.get(subArrays[(int)nDims - 2], i);
                        for (int j = 0; j < (int) dimSizes[nDims - 1]; j++) {
			   goon = true;
			   byte abyte = ((byte [])aRow)[j];

                           if (minObj != null) {
                            if (minLen == 1) {
                              if (abyte < tmpMin) {
				goon = false;
                                if (filObj != null) ((byte [])aRow)[j] = tmpFil;
                                else ((byte [])aRow)[j] = 0;
                              }
                            } else {
			      if (((byte [])minObj).length > j) {
                                if (abyte < ((byte [])minObj)[j]) {
				  goon = false;
                                  if (filObj != null) ((byte [])aRow)[j] = tmpFil;
                                  else ((byte [])aRow)[j] = 0;
			        }
                              }
                            }
                           }
                           if (goon && maxObj != null) {
                            if (maxLen == 1) {
                              if (abyte > tmpMax) {
                                if (filObj != null) ((byte [])aRow)[j] = tmpFil;
                                else ((byte [])aRow)[j] = 0;
                              }
                            } else {
			      if (((byte [])maxObj).length > j) {
                                if (abyte > ((byte [])maxObj)[j]) {
                                  if (filObj != null) ((byte [])aRow)[j] = tmpFil;
                                  else ((byte [])aRow)[j] = 0;
				}
                              }
                            }
                           }

			}
		    }	
		} else if (dataType == CDF_INT2 || dataType == CDF_UINT1) {
                    short ashort = 0;
                    short tmpMin = 0, tmpMax = 0, tmpFil = 0;
                    if (minObj != null) tmpMin = ((short[])minObj)[0];
                    if (maxObj != null) tmpMax = ((short[])maxObj)[0];
                    if (filObj != null) tmpFil = ((short[])filObj)[0];
                    if (dataType == CDF_UINT1) {
                      if (tmpMin < 0) tmpMin -= (short) 2*Byte.MIN_VALUE;
                      if (tmpMax < 0) tmpMax -= (short) 2*Byte.MIN_VALUE;
                      if (tmpFil < 0) tmpFil -= (short) 2*Byte.MIN_VALUE;
                    }

                    for (int i = 0; i < (int) dimSizes[(int)nDims-2]; i++) {
                        aRow = (short [])Array.get(subArrays[(int)nDims - 2], i);
                        for (int j = 0; j < (int) dimSizes[nDims - 1]; j++) {
			   goon = true;
			   ashort = ((short [])aRow)[j];
			   if (dataType == CDF_UINT1 && ashort < 0) 
			     ashort -= (short) 2*Byte.MIN_VALUE;
                           if (minObj != null) {
                             if (minLen == 1) {
                               if (ashort < tmpMin) {
				 goon = false;
                                 if (filObj != null) ((short [])aRow)[j] = tmpFil;
                                 else ((short [])aRow)[j] = 0;
                               }
                             } else {
			       if (((short [])minObj).length > j) {
                                 short avalue = ((short [])minObj)[j];
                                 if (dataType == CDF_UINT1 && avalue < 0) 
				   avalue -= (short) 2*Byte.MIN_VALUE;
                                 if (ashort < avalue) {
				   goon = false;
                                   if (filObj != null) ((short [])aRow)[j] = tmpFil;
                                   else ((short [])aRow)[j] = 0;
				 }
                               }
                             }
                           }
                           if (goon && maxObj != null) {
                             if (maxLen == 1) {
                               if (ashort > tmpMax) {
                                 if (filObj != null) ((short [])aRow)[j] = tmpFil;
                                 else ((short [])aRow)[j] = 0;
                               }
                             } else {
			       if (((short [])maxObj).length > j) {
                                 short avalue = ((short [])maxObj)[j];
                                 if (dataType == CDF_UINT1 && avalue < 0) 
				   avalue -= (short) 2*Byte.MIN_VALUE;
                                 if (ashort > avalue) {
                                   if (filObj != null) ((short [])aRow)[j] = tmpFil;
                                   else ((short [])aRow)[j] = 0;
				 }
                               }
                             }
                           }

                        }
		    }
		} else if (dataType == CDF_INT4 || dataType == CDF_UINT2) {
                    int aint = 0;
                    int tmpMin = 0, tmpMax = 0, tmpFil = 0;
                    if (minObj != null) tmpMin = ((int[])minObj)[0];
                    if (maxObj != null) tmpMax = ((int[])maxObj)[0];
                    if (filObj != null) tmpFil = ((int[])filObj)[0];
                    if (dataType == CDF_UINT2) {
                      if (tmpMin < 0) tmpMin -= (int) 2*Short.MIN_VALUE;
                      if (tmpMax < 0) tmpMax -= (int) 2*Short.MIN_VALUE;
                      if (tmpFil < 0) tmpFil -= (int) 2*Short.MIN_VALUE;
                    }

                    for (int i = 0; i < (int) dimSizes[(int)nDims-2]; i++) {
                        aRow = (int [])Array.get(subArrays[(int)nDims - 2], i);
                        for (int j = 0; j < (int) dimSizes[nDims - 1]; j++) {
			   goon = true;
			   aint = ((int [])aRow)[j];
			   if (dataType == CDF_UINT2 && aint < 0) 
			     aint -= (int) 2*Short.MIN_VALUE;

                           if (minObj != null) {
                             if (minLen == 1) {
                               if (aint < tmpMin) {
				 goon = false;
                                 if (filObj != null) ((int [])aRow)[j] = tmpFil;
                                 else ((int [])aRow)[j] = 0;
                               }
                             } else {
			       if (((int [])minObj).length > j) {
                                 int avalue = ((int [])minObj)[j];
                                 if (dataType == CDF_UINT2 && avalue < 0) 
				   avalue -= (int) 2*Short.MIN_VALUE;
                                 if (aint < avalue) {
				   goon = false;
                                   if (filObj != null) ((int [])aRow)[j] = tmpFil;
                                   else ((int [])aRow)[j] = 0;
				 }
                               }
                             }
                           }
                           if (goon && maxObj != null) {
                             if (maxLen == 1) {
                               if (aint > tmpMin) {
                                 if (filObj != null) ((int [])aRow)[j] = tmpFil;
                                 else ((int [])aRow)[j] = 0;
                               }
                             } else {
			       if (((int [])maxObj).length > j) {
                                 int avalue = ((int [])maxObj)[j];
                                 if (dataType == CDF_UINT2 && avalue < 0) 
				   avalue -= (int) 2*Short.MIN_VALUE;
                                 if (aint > avalue) {
                                   if (filObj != null) ((int [])aRow)[j] = tmpFil;
                                   else ((int [])aRow)[j] = 0;
				 } 
                               }
                             }
                           }
                        }
		    }
		} else if (dataType == CDF_UINT4 || dataType == CDF_INT8 ||
                           dataType == CDF_TIME_TT2000) {
                    long along = 0;
                    long tmpMin = 0L, tmpMax = 0L, tmpFil = 0L;
                    if (minObj != null) tmpMin = ((long[])minObj)[0];
                    if (maxObj != null) tmpMax = ((long[])maxObj)[0];
                    if (filObj != null) tmpFil = ((long[])filObj)[0];
                    if (dataType == CDF_UINT4) {
                      if (tmpMin < 0) tmpMin -= (long) 2*Integer.MIN_VALUE;
                      if (tmpMax < 0) tmpMax -= (long) 2*Integer.MIN_VALUE;
                      if (tmpFil < 0) tmpFil -= (long) 2*Integer.MIN_VALUE;
                    }
                    for (int i = 0; i < (int) dimSizes[(int)nDims-2]; i++) {
                        aRow = (long [])Array.get(subArrays[(int)nDims - 2], i);
                        for (int j = 0; j < (int) dimSizes[nDims - 1]; j++) {
                           goon = true;
			   along = ((long [])aRow)[j];
			   if (dataType == CDF_UINT4)
                             if (along < 0) along -= (long) 2*Integer.MIN_VALUE;
                           if (minObj != null) {
                             if (minLen == 1) {
                               if (along < tmpMin) {
				 goon = false;
                                 if (filObj != null) ((long [])aRow)[j] = tmpFil;
                                 else ((long [])aRow)[j] = 0;
                               }
                             } else {
			       if (((long [])minObj).length > j) {
                                 long avalue = ((long [])minObj)[j];
                                 if (dataType == CDF_UINT4)
                                   if (avalue < 0) avalue -= (long) 2*Integer.MIN_VALUE;
                                 if (along < avalue) {
				   goon = false;
                                   if (filObj != null) ((long [])aRow)[j] = tmpFil;
                                   else ((long [])aRow)[j] = 0;
				 }
                               }
                             }
                           }
                           if (goon && maxObj != null) {
                             if (maxLen == 1) {
                               if (along > tmpMax) {
                                 if (filObj != null) ((long [])aRow)[j] = tmpFil;
                                 else ((long [])aRow)[j] = 0;
                               }
                             } else {
			       if (((long [])maxObj).length > j) {
                                 long avalue = ((long [])maxObj)[j];
                                 if (dataType == CDF_UINT4)
                                   if (avalue < 0) avalue -= (long) 2*Integer.MIN_VALUE;
                                 if (along > avalue) {
                                   if (filObj != null) ((long [])aRow)[j] = tmpFil;
                                   else ((long [])aRow)[j] = 0;
				 }
                               }
                             }
                           }

                        }
		    }
		} else if (dataType == CDF_REAL4 || dataType == CDF_FLOAT) {
		    float tmpMin = 0.0F, tmpMax = 0.0F, tmpFil = 0.0F;
                    if (minObj != null && minLen == 1)
                        tmpMin = ((float[])minObj)[0];
                    if (maxObj != null && maxLen == 1)
                        tmpMax = ((float[])maxObj)[0];
                    if (filObj != null)
                        tmpFil = ((float[])filObj)[0];

                    for (int i = 0; i < (int) dimSizes[(int)nDims-2]; i++) {
                        aRow = (float [])Array.get(subArrays[(int)nDims - 2], i);
                        for (int j = 0; j < (int) dimSizes[nDims - 1]; j++) {
                           goon = true;
 			   float afloat = ((float [])aRow)[j];
                           if (minObj != null) {
                            if (minLen == 1) {
                              if (afloat < tmpMin) {
				  goon = false;
                                  if (filObj != null) ((float [])aRow)[j] = tmpFil;
                                  else ((float [])aRow)[j] = 0.0F;
                              }
                            } else {
			      if (((float [])minObj).length > j) {
                                if (afloat < ((float [])minObj)[j]) {
				  goon = false;
                                  if (filObj != null) ((float [])aRow)[j] = tmpFil;
                                  else ((float [])aRow)[j] = 0.0F;
				}
                              }
                            }
                           }
                           if (goon && maxObj != null) {
                            if (maxLen == 1) {
                              if (afloat > tmpMax) {
                                  if (filObj != null) ((float [])aRow)[j] = tmpFil;
                                  else ((float [])aRow)[j] = 0.0F;
                              }
                            } else {
			      if (((float [])maxObj).length > j) {
                                if (afloat > ((float [])maxObj)[j]) {
                                  if (filObj != null) ((float [])aRow)[j] = tmpFil;
                                  else ((float [])aRow)[j] = 0.0F;
				}
                              }
                            }
                           }

                        }
		    }
		} else if (dataType == CDF_REAL8 || dataType == CDF_DOUBLE ||
			   dataType == CDF_EPOCH) {
		    double tmpMin = 0.0D, tmpMax = 0.0D, tmpFil = 0.0D;
                    if (minObj != null && minLen == 1)
                        tmpMin = ((double[])minObj)[0];
                    if (maxObj != null && maxLen == 1)
                        tmpMax = ((double[])maxObj)[0];
                    if (filObj != null)
                        tmpFil = ((double[])filObj)[0];

                    for (int i = 0; i < (int) dimSizes[(int)nDims-2]; i++) {
                        aRow = (double [])Array.get(subArrays[(int)nDims - 2], i);
                        for (int j = 0; j < (int) dimSizes[nDims - 1]; j++) {
                           goon = true;
			   double adouble = ((double [])aRow)[j];
                           if (minObj != null) {
                            if (minLen == 1) {
                              if (adouble < tmpMin) {
				  goon = false;
                                  if (filObj != null) ((double [])aRow)[j] = tmpFil;
                                  else ((double [])aRow)[j] = 0.0;
                              }
                            } else {
			      if (((double [])minObj).length > j) {
                                if (adouble < ((double [])minObj)[j]) {
				  goon = false;
                                  if (filObj != null) ((double [])aRow)[j] = tmpFil;
                                  else ((double [])aRow)[j] = 0.0;
				}
                              }
                            }
                           }
                           if (goon && maxObj != null) {
                            if (maxLen == 1) {
                              if (adouble > tmpMax) {
                                  if (filObj != null) ((double [])aRow)[j] = tmpFil;
                                  else ((double [])aRow)[j] = 0.0;
                              }
                            } else {
			      if (((double [])maxObj).length > j) {
                                if (adouble > ((double [])maxObj)[j]) {
                                  if (filObj != null) ((double [])aRow)[j] = tmpFil;
                                  else ((double [])aRow)[j] = 0.0;
				}
                              }
                            }
                           }
                        }
		    }
                } else if (dataType == CDF_EPOCH16) {
                    double[] tmpMin = new double[] {0.0D, 0.0D},
			     tmpMax = new double[] {0.0D, 0.0D}, 
			     tmpFil = new double[] {0.0D, 0.0D};
                    if (minObj != null && minLen == 1) {
                        tmpMin[0] = ((double[])minObj)[0];
			tmpMin[1] = ((double[])minObj)[1];
                    }
		    if (maxObj != null && maxLen == 1) {
                        tmpMax[0] = ((double[])maxObj)[0];
			tmpMax[1] = ((double[])maxObj)[1];
                    }
		    if (filObj != null) {
                        tmpFil[0] = ((double[])filObj)[0];
			tmpFil[1] = ((double[])filObj)[1];
		    }

                    for (int i = 0; i < (int) dimSizes[(int)nDims-2]; i++) {
                        aRow = (double [])Array.get(subArrays[(int)nDims - 2], i);
                        for (int j = 0; j < (int) dimSizes[nDims - 1]; j=j+2) {
                           goon = true;
                           double[] adouble = new double[2];
			   adouble[0] = ((double [])aRow)[2*j];
			   adouble[1] = ((double [])aRow)[2*j+1];
                           if (minObj != null) {
                            if (minLen == 1) {
                              if (adouble[0] < tmpMin[0] ||
				  (adouble[0] == tmpMin[0] &&
				   adouble[1] < tmpMin[1])) {
                                  goon = false;
                                  if (filObj != null) {
				    ((double [])aRow)[2*j] = tmpFil[0];
				    ((double [])aRow)[2*j+1] = tmpFil[1];
                                  } else {
				    ((double [])aRow)[2*j] = 0.0;
				    ((double [])aRow)[2*j+1] = 0.0;
				  }
                              }
                            } else {
                              if (((double [])minObj).length > j) {
                                if (adouble[0] < ((double [])minObj)[2*j] ||
				    (adouble[0] == ((double [])minObj)[2*j] &&
				     adouble[1] < ((double [])minObj)[2*j+1] )) {
                                  goon = false;
                                  if (filObj != null) {
				    ((double [])aRow)[2*j] = tmpFil[0];
				    ((double [])aRow)[2*j+1] = tmpFil[1];
				  } else {
                                    ((double [])aRow)[2*j] = 0.0;
				    ((double [])aRow)[2*j+1] = 0.0;
				  }
                                }
                              }
                            }
                           }
                           if (goon && maxObj != null) {
                             if (maxLen == 1) {
                               if (adouble[0] > tmpMax[0] || 
				  (adouble[0] == tmpMax[0]  &&
				   adouble[1] > tmpMax[1] )) {
                                  if (filObj != null) {
				    ((double [])aRow)[2*j] = tmpFil[0];
				    ((double [])aRow)[2*j+1] = tmpFil[1];
				  } else {
                                    ((double [])aRow)[2*j] = 0.0;
				    ((double [])aRow)[2*j+1] = 0.0;
				  }
                               }
			     }
                           } else {
                             if (((double [])maxObj).length > j) {
                               if (adouble[0] > ((double [])maxObj)[2*j] ||
				   (adouble[0] > ((double [])maxObj)[2*j] &&
				    adouble[1] > ((double [])maxObj)[2*j+1] )) {
                                 if (filObj != null) {
				   ((double [])aRow)[2*j] = tmpFil[0];
				   ((double [])aRow)[2*j+1] = tmpFil[1];
				 } else {
                                   ((double [])aRow)[2*j] = 0.0;
				   ((double [])aRow)[2*j+1] = 0.0;
				 }
                               }
                             }
                           }
                        }
                    }
		}
                n += dimSizes[nDims - 1];
            }
	}
	 return _dataArray;
    }


/** Used to determine the boundaries
 */

    private long product(long [] array, int start, int stop) {
        long product = 1;
        for (int i = start; i < stop; i++)
            if (array[i] > 1) product *= array[i];

        return product;
    }

    protected BuildProgressPanel getProgressPanel() {
	return progressPanel;
    }


/**
 * Create a thread to dispose the progress panel so that other threads which were
 * used to update the progress bar could finish before this thread can start.
 */

    class CleanProgress extends Thread {

        public void run() {
	  progressPanel.dispose();
	  progressPanel = null;
	  if (myCDFExport.MacOS) System.gc();
        }
    };


}
