/** Gets called by the {@link DataManager} when this DataSource has been removed. */
 public void doRemove() {
   if (getAdapters() != null) {
     for (RadarAdapter ra : getAdapters()) {
       ra.doRemove();
     }
   }
   super.doRemove();
 }
 /**
  * This is called when the CacheManager detects the need ot clear memory. It is intended to be
  * overwritten by derived classes that are holding cached data that is not in the normal putCache
  * facilities provided by this class since that data is actually managed by the CacheManager
  */
 public void clearCachedData() {
   super.clearCachedData();
   List<RadarAdapter> adapters = getAdapters();
   for (Iterator iter = adapters.iterator(); iter.hasNext(); ) {
     RadarAdapter adapter = (RadarAdapter) iter.next();
     adapter.clearCachedData();
   }
 }
  /**
   * Get the data for the given DataChoice and selection criteria.
   *
   * @param dataChoice DataChoice for selection
   * @param category DataCategory for the DataChoice (not used)
   * @param subset subsetting criteria
   * @param requestProperties extra request properties
   * @return the Data object for the request
   * @throws RemoteException couldn't create a remote data object
   * @throws VisADException couldn't create the data
   */
  protected Data getDataInner(
      final DataChoice dataChoice,
      DataCategory category,
      final DataSelection subset,
      final Hashtable requestProperties)
      throws VisADException, RemoteException {

    try {
      List times = null;
      if (subset != null) {
        times = getTimesFromDataSelection(subset, dataChoice);
      }
      if (times == null) {
        times = dataChoice.getSelectedDateTimes();
      }

      List dtimes = subset.getTimeDriverTimes();

      if (dtimes != null && useDriverTime == false) {
        useDriverTime = true;
      }

      List<RadarAdapter> adapters = getAdapters();

      DateTime[] realDateTimes = new DateTime[adapters.size()];
      for (int i = 0; i < adapters.size(); i++) {
        realDateTimes[i] = ((RadarAdapter) adapters.get(i)).getBaseTime();
      }
      Arrays.sort(realDateTimes);
      // Flip it to get youngest date first
      boolean isRealTime = isRealTime();
      if (isRealTime) {
        realDateTimes =
            (DateTime[]) Misc.reverseArray(realDateTimes, new DateTime[realDateTimes.length]);
      }
      // if use time driver
      if (useDriverTime) {
        List tests = resetTimesList(realDateTimes, times);
        if (!compareTimeLists(times, tests)) {
          reloadData();
          adapters = getAdapters();

          realDateTimes = new DateTime[adapters.size()];
          for (int i = 0; i < adapters.size(); i++) {
            realDateTimes[i] = ((RadarAdapter) adapters.get(i)).getBaseTime();
          }
          Arrays.sort(realDateTimes);
          // Flip it to get youngest date first
          isRealTime = isRealTime();
          if (isRealTime) {
            realDateTimes =
                (DateTime[]) Misc.reverseArray(realDateTimes, new DateTime[realDateTimes.length]);
          }
          tests = resetTimesList(realDateTimes, times);
        }
        times = tests;
      }
      // if times are null, then that means all times
      DateTime[] dateTimes = null;

      if ((times == null) || (times.size() == 0)) {
        dateTimes = realDateTimes;
      } else {
        dateTimes = new DateTime[times.size()];
        for (int i = 0; i < times.size(); i++) {
          Object time = times.get(i);
          if (time instanceof TwoFacedObject) {
            int index = ((Integer) ((TwoFacedObject) time).getId()).intValue();
            dateTimes[i] = realDateTimes[index];
          } else if (time instanceof DateTime) {
            dateTimes[i] = (DateTime) time;
          }
        }
      }
      Arrays.sort(dateTimes);
      final Data[] datas = new Data[dateTimes.length];
      int timeIndex = 0;
      final MathType[] mt = {null};
      // create a new field of (Time -> (radar data)).
      // fill in the times array and data array with dates/data
      // only from those adapters which match the selected times.
      // if a data object is null, stick it in the list.
      // if all are null, then the MathType (mt) will never get set,
      // so return null.
      //            System.err.println ("Reading " + adapters.size() + " radar files");
      int cnt = 0;
      ThreadManager threadManager = new visad.util.ThreadManager("radar data reading");

      for (Iterator iter = adapters.iterator(); iter.hasNext(); ) {
        final RadarAdapter adapter = (RadarAdapter) iter.next();
        timeIndex = Arrays.binarySearch(dateTimes, adapter.getBaseTime());
        //              System.err.println ("timeIndex:" + timeIndex);
        if (timeIndex < 0) {
          continue;
        }
        cnt++;
        LogUtil.message("Time: " + (cnt) + "/" + dateTimes.length + " From:" + toString());
        final int theTimeIndex = timeIndex;
        threadManager.addRunnable(
            new visad.util.ThreadManager.MyRunnable() {
              public void run() throws Exception {
                Trace.call1("RDS.getData");
                Data d = adapter.getData(dataChoice, subset, requestProperties);
                Trace.call2("RDS.getData");
                datas[theTimeIndex] = d;
                if (d != null) {
                  mt[0] = d.getType();
                } else {
                }
              }
            });
      }

      try {
        // threadManager.debug = true;
        threadManager.runInParallel(getDataContext().getIdv().getMaxDataThreadCount());
      } catch (VisADException ve) {
        LogUtil.printMessage(ve.toString());
      }

      if (mt[0] == null) {
        return null;
      }

      FunctionType ft = new FunctionType(RealType.Time, mt[0]);
      SampledSet domainSet =
          (dateTimes.length == 1)
              ? (SampledSet) new SingletonSet(new RealTuple(dateTimes))
              : (SampledSet) DateTime.makeTimeSet(dateTimes);
      FieldImpl fi = new FieldImpl(ft, domainSet);
      fi.setSamples(datas, false);
      return fi;
    } catch (Exception exc) {
      logException("Creating obs", exc);
    }
    return null;
  }