private InvAccess getImageAccess(
      InvDataset invDataset, ucar.nc2.util.CancelTask task, Result result) {

    List<InvAccess> accessList =
        new ArrayList<InvAccess>(invDataset.getAccess()); // a list of all the accesses
    while (accessList.size() > 0) {
      InvAccess access = chooseImageAccess(accessList);
      if (access != null) return access;

      // next choice is resolver type.
      access = invDataset.getAccess(ServiceType.RESOLVER);

      // no valid access
      if (access == null) {
        result.errLog.format("No access that could be used for Image Type %s %n", invDataset);
        return null;
      }

      // deal with RESOLVER type
      String datasetLocation = access.getStandardUrlName();
      InvDatasetImpl rds = openResolver(datasetLocation, task, result);
      if (rds == null) return null;

      // use the access list from the resolved dataset
      accessList = new ArrayList<InvAccess>(invDataset.getAccess());
    } // loop over accesses

    return null;
  }
  /**
   * Getting invDataset list for a single radar station.
   *
   * @param stnName radar station name
   * @param start of the time
   * @param end of the time
   * @return list of invDataset
   * @throws IOException java io exception
   */
  private DqcRadarDatasetInfo queryRadarStation(String stnName, Date start, Date end)
      throws IOException {
    // http://motherlode.ucar.edu:9080/thredds/idd/radarLevel2?returns=catalog&stn=KFTG&dtime=latest
    StringBuffer queryb = new StringBuffer();

    queryb.append(dqc.getQuery().getUriResolved().toString());
    queryb.append("serviceType=OPENDAP");
    queryb.append("&stn=" + stnName);
    if ((start == null) && (end == null)) {
      queryb.append("&dtime=all");
    } else {
      String stime = DateUtil.getTimeAsISO8601(start);
      String etime = DateUtil.getTimeAsISO8601(end);
      queryb.append("&dateStart=" + stime);
      queryb.append("&dateEnd=" + etime);
    }

    URI catalogURI;
    try {
      catalogURI = new URI(queryb.toString());
    } catch (java.net.URISyntaxException e) {
      throw new IOException("** MalformedURLException on URL <" + ">\n" + e.getMessage() + "\n");
    }

    InvCatalogFactory factory = new InvCatalogFactory("default", false);

    InvCatalogImpl catalog = (InvCatalogImpl) factory.readXML(catalogURI);
    StringBuilder buff = new StringBuilder();
    if (!catalog.check(buff)) {
      throw new IOException("Invalid catalog <" + catalogURI + ">\n" + buff.toString());
    }

    List datasets = catalog.getDatasets();

    InvDataset idata = (InvDataset) datasets.get(0);
    //    List ddate = idata.getDates();

    ArrayList dsets = (ArrayList) idata.getDatasets();

    ArrayList absTimeList = new ArrayList();
    ArrayList dURIList = new ArrayList();
    ArrayList dInvList = new ArrayList();

    for (int i = 0; i < dsets.size(); i++) {
      InvDataset tdata = (InvDataset) dsets.get(i);
      List acess = tdata.getAccess();
      List dates = tdata.getDates();
      InvAccess ia = (InvAccess) acess.get(0);
      URI d = ia.getStandardUri();
      Date date = DateUnit.getStandardOrISO(dates.get(0).toString());
      absTimeList.add(date);
      dURIList.add(new DatasetURIInfo(d, date));
      dInvList.add(new InvDatasetInfo(tdata, date));
    }

    DqcRadarDatasetInfo dri = new DqcRadarDatasetInfo(absTimeList, dURIList, dInvList);

    return dri;
  }
  private NetcdfDataset openDataset(
      InvDataset invDataset, boolean acquire, ucar.nc2.util.CancelTask task, Result result)
      throws IOException {

    IOException saveException = null;

    List<InvAccess> accessList =
        new ArrayList<InvAccess>(invDataset.getAccess()); // a list of all the accesses
    while (accessList.size() > 0) {
      InvAccess access = chooseDatasetAccess(accessList);

      // no valid access
      if (access == null) {
        result.errLog.format("No access that could be used in dataset %s %n", invDataset);
        if (saveException != null) throw saveException;
        return null;
      }

      String datasetLocation = access.getStandardUrlName();
      ServiceType serviceType = access.getService().getServiceType();
      if (debugOpen)
        System.out.println("ThreddsDataset.openDataset try " + datasetLocation + " " + serviceType);

      // deal with RESOLVER type
      if (serviceType == ServiceType.RESOLVER) {
        InvDatasetImpl rds = openResolver(datasetLocation, task, result);
        if (rds == null) return null;
        accessList = new ArrayList<InvAccess>(rds.getAccess());
        continue;
      }

      // ready to open it through netcdf API
      NetcdfDataset ds;

      // try to open
      try {
        ds = openDataset(access, acquire, task, result);

      } catch (IOException e) {
        result.errLog.format("Cant open %s %n err=%s%n", datasetLocation, e.getMessage());
        if (debugOpen) {
          System.out.println("Cant open= " + datasetLocation + " " + serviceType);
          e.printStackTrace();
        }

        accessList.remove(access);
        saveException = e;
        continue;
      }

      result.accessUsed = access;
      return ds;
    } // loop over accesses

    if (saveException != null) throw saveException;
    return null;
  }
  /**
   * Getting URI for a single radar station.
   *
   * @param stnName radar station name
   * @param absTime is absolute time
   * @return URI
   * @throws IOException java io exception
   */
  public URI getRadarDatasetURI(String stnName, Date absTime) throws IOException {
    // absTime is a member of  datasetsDateURI
    InvDataset invdata = queryRadarStation(stnName, absTime);
    List<InvAccess> acess = invdata.getAccess();
    InvAccess ia = (InvAccess) acess.get(0);
    URI ui = ia.getStandardUri();

    if (ui == null) {
      throw new IOException("Invalid time selected: " + absTime.toString() + "\n");
    }

    return ui;
  }
  /**
   * _more_
   *
   * @param stnName _more_
   * @param productID _more_
   * @param absTime _more_
   * @return _more_
   * @throws IOException _more_
   */
  public URI getRadarDatasetURI(String stnName, String productID, Date absTime) throws IOException {
    // absTime is a member of  datasetsDateURI

    if (productID == null) {
      return getRadarDatasetURI(stnName, absTime);
    }

    InvDataset invdata = queryRadarStation(stnName, productID, absTime);
    /*  List dsets = idata.getDatasets();
    int siz = dsets.size();
    if(siz != 1)
        return null;

    InvDataset invdata = (InvDataset)dsets.get(0);     */
    List acess = invdata.getAccess();
    InvAccess ia = (InvAccess) acess.get(0);
    URI ui = ia.getStandardUri();

    if (ui == null) {
      throw new IOException("Invalid time selected: " + absTime.toString() + "\n");
    }

    return ui;
  }
  /**
   * Getting invDataset list for a single radar station.
   *
   * @param stnName radar station name
   * @param productID _more_
   * @param start of the time
   * @param end of the time
   * @return list of invDataset
   * @throws IOException java io exception
   */
  private TDSRadarDatasetInfo queryRadarStation(
      String stnName, String productID, Date start, Date end) throws IOException {
    // http://motherlode.ucar.edu:9080/thredds/idd/radarLevel2?returns=catalog&stn=KFTG&dtime=latest
    StringBuilder queryb = new StringBuilder();
    String baseURI = dsc_location.replaceFirst("/dataset.xml", "?");
    queryb.append(baseURI);
    queryb.append("stn=" + stnName);
    if (productID != null) {
      queryb.append("&var=" + productID);
    }
    if ((start == null) && (end == null)) {
      queryb.append("&time=present");
    } else if (end == null) {
      String stime = DateUtil.getTimeAsISO8601(start).replaceAll("GMT", "");
      queryb.append("&time_start=" + stime);
      queryb.append("&time_end=present");
    } else {
      String stime = DateUtil.getTimeAsISO8601(start).replaceAll("GMT", "");
      String etime = DateUtil.getTimeAsISO8601(end).replaceAll("GMT", "");
      queryb.append("&time_start=" + stime);
      queryb.append("&time_end=" + etime);
    }

    URI catalogURI;
    try {
      catalogURI = new URI(queryb.toString());
    } catch (java.net.URISyntaxException e) {
      throw new IOException("** MalformedURLException on URL <" + ">\n" + e.getMessage() + "\n");
    }

    InvCatalogFactory factory = new InvCatalogFactory("default", false);

    // visad.util.Trace.call1("TDSRadarDatasetCollection.readXML");
    InvCatalogImpl catalog = (InvCatalogImpl) factory.readXML(catalogURI);
    // visad.util.Trace.call2("TDSRadarDatasetCollection.readXML");
    StringBuilder buff = new StringBuilder();
    // visad.util.Trace.call1("TDSRadarDatasetCollection.checkCatalog");
    if (!catalog.check(buff)) {
      throw new IOException("Invalid catalog <" + catalogURI + ">\n" + buff.toString());
    }
    // visad.util.Trace.call2("TDSRadarDatasetCollection.checkCatalog");

    List<InvDataset> datasets = catalog.getDatasets();

    InvDataset idata = (InvDataset) datasets.get(0);

    List<InvDataset> dsets = idata.getDatasets();

    List<Date> absTimeList = new ArrayList<Date>();
    List<DatasetURIInfo> dURIList = new ArrayList<DatasetURIInfo>();
    List<InvDatasetInfo> dInvList = new ArrayList<InvDatasetInfo>();

    // visad.util.Trace.call1("TDSRadarDatasetCollection.getLists");
    for (InvDataset tdata : dsets) {
      List<InvAccess> acess = tdata.getAccess();
      List<DateType> dates = tdata.getDates();
      InvAccess ia = (InvAccess) acess.get(0);
      URI d = ia.getStandardUri();
      Date date = ((DateType) dates.get(0)).getDate();
      absTimeList.add(date);
      dURIList.add(new DatasetURIInfo(d, date));
      dInvList.add(new InvDatasetInfo(tdata, date));
    }
    // visad.util.Trace.call2("TDSRadarDatasetCollection.getLists");

    TDSRadarDatasetInfo dri = new TDSRadarDatasetInfo(absTimeList, dURIList, dInvList);

    return dri;
  }
  public ThreddsDataFactory.Result openFeatureDataset(
      FeatureType wantFeatureType,
      InvDataset invDataset,
      ucar.nc2.util.CancelTask task,
      Result result)
      throws IOException {

    result.featureType = invDataset.getDataType();
    if (result.featureType == null) result.featureType = wantFeatureType;

    // look for remote FeatureDataset
    if ((result.featureType != null) && result.featureType.isPointFeatureType()) {
      InvAccess access = findAccessByServiceType(invDataset.getAccess(), ServiceType.CdmrFeature);
      if (access != null) return openFeatureDataset(result.featureType, access, task, result);
    }

    // special handling for images
    if (result.featureType == FeatureType.IMAGE) {
      InvAccess access = getImageAccess(invDataset, task, result);
      if (access != null) {
        return openFeatureDataset(result.featureType, access, task, result);
      } else result.fatalError = true;
      return result;
    }

    // special handling for DQC
    InvAccess qc = invDataset.getAccess(ServiceType.QC);
    if (qc != null) {
      String dqc_location = qc.getStandardUrlName();

      if (result.featureType == FeatureType.STATION) {

        /* DqcFactory dqcFactory = new DqcFactory(true);
        QueryCapability dqc = dqcFactory.readXML(dqc_location);
        if (dqc.hasFatalError()) {
          result.errLog.append(dqc.getErrorMessages());
          result.fatalError = true;
        } */

        result.featureDataset =
            null; // LOOK FIX ucar.nc2.thredds.DqcStationObsDataset.factory(invDataset,
                  // dqc_location, result.errLog);
        result.fatalError = (result.featureDataset == null);

      } else {
        result.errLog.format("DQC must be station DQC, dataset = %s %n", invDataset.getName());
        result.fatalError = true;
      }

      return result;
    }

    NetcdfDataset ncd = openDataset(invDataset, true, task, result.errLog);
    if (null != ncd)
      result.featureDataset =
          FeatureDatasetFactoryManager.wrap(result.featureType, ncd, task, result.errLog);

    if (null == result.featureDataset) result.fatalError = true;
    else {
      result.location = result.featureDataset.getLocation();
      if ((result.featureType == null) && (result.featureDataset != null))
        result.featureType = result.featureDataset.getFeatureType();
    }

    return result;
  }