opendap/src/main/java/ucar/nc2/dods/DODSNetcdfFile.java
private void parseGlobalAttributes(DAS das, DodsV root, DODSNetcdfFile dodsfile) {

    List<DODSAttribute> atts = root.attributes;
    for (ucar.nc2.Attribute ncatt : atts) {
      rootGroup.addAttribute(ncatt);
    }

    // loop over attribute tables, collect global attributes
    Enumeration tableNames = das.getNames();
    while (tableNames.hasMoreElements()) {
      String tableName = (String) tableNames.nextElement();
      AttributeTable attTable = das.getAttributeTableN(tableName);
      if (attTable == null)
        continue; // should probably never happen

            /* if (tableName.equals("NC_GLOBAL") || tableName.equals("HDF_GLOBAL")) {
        java.util.Enumeration attNames = attTable.getNames();
        while (attNames.hasMoreElements()) {
          String attName = (String) attNames.nextElement();
          dods.dap.Attribute att = attTable.getAttribute(attName);

          DODSAttribute ncatt = new DODSAttribute( attName, att);
          addAttribute( null, ncatt);
        }

          } else */

      if (tableName.equals("DODS_EXTRA")) {
        Enumeration attNames = attTable.getNames();
        while (attNames.hasMoreElements()) {
          String attName = (String) attNames.nextElement();
          if (attName.equals("Unlimited_Dimension")) {
            opendap.dap.Attribute att = attTable.getAttribute(attName);
            DODSAttribute ncatt = new DODSAttribute(attName, att);
            setUnlimited(ncatt.getStringValue());
          } else
            logger.warn(" Unknown DODS_EXTRA attribute = " + attName + " " + location);
        }

      } else if (tableName.equals("EXTRA_DIMENSION")) {
        Enumeration attNames = attTable.getNames();
        while (attNames.hasMoreElements()) {
          String attName = (String) attNames.nextElement();
          opendap.dap.Attribute att = attTable.getAttribute(attName);
          DODSAttribute ncatt = new DODSAttribute(attName, att);
          int length = ncatt.getNumericValue().intValue();
          Dimension extraDim = new Dimension(attName, length);
          addDimension(null, extraDim);
        }

      } /* else if (null == root.findDodsV( tableName, false)) {
  addAttributes(attTable.getName(), attTable);
      } */
    }
  }
private void parseGlobalAttributes(DAS das, DodsV root, DODSNetcdfFile dodsfile) {

    List<DODSAttribute> atts = root.attributes;
    for (ucar.nc2.Attribute ncatt : atts) {
      rootGroup.addAttribute(ncatt);
    }

    // loop over attribute tables, collect global attributes
    Enumeration tableNames = das.getNames();
    while (tableNames.hasMoreElements()) {
      String tableName = (String) tableNames.nextElement();
      AttributeTable attTable = das.getAttributeTableN(tableName);
      if (attTable == null)
        continue; // should probably never happen

            /* if (tableName.equals("NC_GLOBAL") || tableName.equals("HDF_GLOBAL")) {
        java.util.Enumeration attNames = attTable.getNames();
        while (attNames.hasMoreElements()) {
          String attName = (String) attNames.nextElement();
          dods.dap.Attribute att = attTable.getAttribute(attName);

          DODSAttribute ncatt = new DODSAttribute( attName, att);
          addAttribute( null, ncatt);
        }

          } else */

      if (tableName.equals("DODS_EXTRA")) {
        Enumeration attNames = attTable.getNames();
        while (attNames.hasMoreElements()) {
          String attName = (String) attNames.nextElement();
          if (attName.equals("Unlimited_Dimension")) {
            opendap.dap.Attribute att = attTable.getAttribute(attName);
            DODSAttribute ncatt = new DODSAttribute(attName, att);
            setUnlimited(ncatt.getStringValue());
          } else
            logger.warn(" Unknown DODS_EXTRA attribute = " + attName + " " + location);
        }

      } else if (tableName.equals("EXTRA_DIMENSION")) {
        Enumeration attNames = attTable.getNames();
        while (attNames.hasMoreElements()) {
          String attName = (String) attNames.nextElement();
          opendap.dap.Attribute att = attTable.getAttribute(attName);
          DODSAttribute ncatt = new DODSAttribute(attName, att);
          int length = ncatt.getNumericValue().intValue();
          Dimension extraDim = new Dimension(attName, length);
          addDimension(null, extraDim);
        }

      } /* else if (null == root.findDodsV( tableName, false)) {
  addAttributes(attTable.getName(), attTable);
      } */
    }
  }
/* parse the DDS, creating a tree of DodsV objects
private ArrayList parseDDS(DDS dds) throws IOException {
ArrayList dodsVlist	 = new ArrayList();

recursively get the Variables from the DDS
Enumeration variables = dds.getVariables();
parseVariables( null, variables, dodsVlist);

assign depth first sequence number
nextInSequence = 0;
assignSequence( dodsVlist);
return dodsVlist;
}

DDS -> {BaseType} for arrays, BaseType = DArray -> {elemType}
here we 1) put all Variables into a DodsV, 2) unravel DConstructors (DSequence, DStructure, DGrid)
3) for Darray, we put Variable = elemType, and store the darray seperately, not in the heirarchy.
so you need to get the parent from the dodsV.
private void parseVariables( DodsV parent, Enumeration variables, ArrayList dodsVlist) {
while (variables.hasMoreElements()) {
dods.dap.BaseType bt = (dods.dap.BaseType) variables.nextElement();
DodsV dodsV = new DodsV( parent, bt);
dodsVlist.add(dodsV);
if (bt instanceof DConstructor) {
DConstructor dcon = (DConstructor) bt;
java.util.Enumeration enumerate2 = dcon.getVariables();
parseVariables( dodsV, enumerate2, dodsV.children);

} else if (bt instanceof DArray) {
DArray da = (DArray) bt;

BaseType elemType = da.getPrimitiveVector().getTemplate();
dodsV.bt = elemType;
dodsV.darray = da;

if (elemType instanceof DConstructor) { // note that for DataDDS, cant traverse this further to find the data.
DConstructor dcon = (DConstructor) elemType;
java.util.Enumeration nestedVariables = dcon.getVariables();
parseVariables( dodsV, nestedVariables, dodsV.children);
}
}
}
}

assign depth first sequence number
private int nextInSequence = 0;
private void assignSequence( ArrayList dodsVlist) {
for (int i = 0; i < dodsVlist.size(); i++) {
DodsV dodsV =  (DodsV) dodsVlist.get(i);
assignSequence( dodsV.children);
dodsV.seq = nextInSequence;
nextInSequence++;
}
}

parse the DAS, assign attribute tables to the DodsV objects.
nested attribute tables actuallly follow the tree we construct with dodsV, so its
easy to assign to correct dodsV.
private void parseDAS(DAS das, ArrayList dodsVlist) throws IOException {
recursively find the Attributes from the DAS
Enumeration tableNames = das.getNames();
parseAttributes( das, tableNames, dodsVlist);
}

private void parseAttributes( DAS das, Enumeration tableNames, ArrayList dodsVlist) {
while (tableNames.hasMoreElements()) {
String tableName = (String) tableNames.nextElement();
AttributeTable attTable = das.getAttributeTable( tableName);

see if there's a matching variable
String name = attTable.getName();
DodsV dodsV = findDodsV( name, dodsVlist, false); // short name matches the table name
if (dodsV != null) {
dodsV.attTable = attTable;
if (debugAttributes) System.out.println("DODSNetcdf getAttributes found <"+name+"> :");
continue;
}
if (debugAttributes) System.out.println("DODSNetcdf getAttributes CANT find <"+name+"> :");
}
}

search the list for a BaseType with given name
private DodsV findDodsV( String name, ArrayList dodsVlist, boolean useDone ) {
for (int i = 0; i < dodsVlist.size(); i++) {
DodsV dodsV =  (DodsV) dodsVlist.get(i);
if (useDone && dodsV.isDone) continue;
if (name.equals( dodsV.bt.getName()))
return dodsV;
}
return null;
}

find the DodsV object in the dataVlist corresponding to the ddsV
private DodsV findDataV( DodsV ddsV, ArrayList dataVlist ) {
if (ddsV.parent != null) {
DodsV parentV = findDataV( ddsV.parent, dataVlist);
if (parentV == null) // dataDDS may not have the structure wrapper
return findDodsV( ddsV.bt.getName(), dataVlist, true);
return findDodsV( ddsV.bt.getName(), parentV.children, true);
}

DodsV dataV =  findDodsV( ddsV.bt.getName(), dataVlist, true);
/* if ((dataV == null) && (ddsV.bt instanceof DGrid)) { // when asking for the Grid array
DodsV gridArray = (DodsV) ddsV.children.get(0);
return findDodsV( gridArray.bt.getName(), dataVlist, true);
} *
return dataV;
}

/* a container for dods basetypes, so we can add some stuff as we process it
class DodsV implements Comparable {
String name; // full name
BaseType bt;
DodsV parent;
ArrayList children = new ArrayList();
DArray darray; // if its an array
AttributeTable attTable;
Array data; // preload
boolean isDone; // nc var has been made
int seq; // "depth first" order

DodsV( DodsV parent, BaseType bt) {
this.parent = parent;
this.bt = bt;
}

public int compareTo(Object o) {
return seq - ((DodsV)o).seq;
}
}