/** Called to alter data in all cells */
 public boolean operateOnData(CharacterData data) {
   if (!(data instanceof ContinuousData)) return false;
   ContinuousData cData = (ContinuousData) data;
   int numItems = cData.getNumItems();
   String[] items = new String[numItems];
   for (int i = 0; i < items.length; i++) {
     if (StringUtil.blank(cData.getItemName(i))) items[i] = "(unnamed)";
     else items[i] = cData.getItemName(i);
   }
   int d =
       ListDialog.queryList(
           containerOfModule(),
           "Rename item",
           "Rename item:",
           MesquiteString.helpString,
           items,
           0);
   if (!MesquiteInteger.isCombinable(d) || d < 0 || d >= numItems) return false;
   else {
     String s =
         MesquiteString.queryString(
             containerOfModule(), "Rename Item", "New name for " + items[d], items[d]);
     if (StringUtil.blank(s)) return false;
     cData.setItemReference(d, NameReference.getNameReference(s));
     return true;
   }
 }
 /**
  * Must be called before a tree is shaded. Goes through all nodes to find states present, to set
  * minima and maxima.
  */
 public void prepareColors(Tree tree, int drawnRoot) {
   minState = MesquiteDouble.unassigned;
   maxState = MesquiteDouble.unassigned;
   calcMinMaxStates(tree, drawnRoot);
   if (getParentData() != null && getParentCharacter() >= 0) {
     int ic = getParentCharacter();
     ContinuousData data = ((ContinuousData) getParentData());
     for (int it = 0; it < data.getNumTaxa(); it++) {
       double s = data.getState(ic, it, 0);
       maxState = MesquiteDouble.maximum(maxState, s);
       minState = MesquiteDouble.minimum(minState, s);
     }
   } else if (getObservedStates() != null) {
     int ic = getParentCharacter();
     ContinuousDistribution data = (ContinuousDistribution) getObservedStates();
     for (int it = 0; it < data.getNumNodes(); it++) {
       double s = data.getState(it);
       maxState = MesquiteDouble.maximum(maxState, s);
       minState = MesquiteDouble.minimum(minState, s);
     }
   }
 }
  // TODO: here should use super.setToClone(data) to handle specssets etc.???
  public CharacterData cloneDataBlock(int icStart, int icEnd, int itStart, int itEnd) {
    int blockChars = icEnd - icStart + 1;
    int blockTaxa = itEnd - itStart + 1;
    boolean[] taxaToClone = new boolean[getNumTaxa()];
    for (int it = 0; it < getNumTaxa(); it++) {
      taxaToClone[it] = it >= itStart && it <= itEnd;
    }
    Taxa taxa = getTaxa().cloneTaxa(taxaToClone);

    ContinuousData cD = new GeographicData(getMatrixManager(), blockTaxa, blockChars, taxa);
    int nItems = getNumItems();
    cD.setItemsAs(this);
    for (int i = 0; i < nItems; i++) {
      Double2DArray imatrix = null;
      imatrix = cD.getItem(i);
      Double2DArray oldMatrix = getItem(i);
      for (int ic = icStart; ic <= icEnd; ic++)
        for (int it = itStart; it <= itEnd; it++)
          imatrix.setValue(ic - icStart, it - itStart, oldMatrix.getValue(ic, it));
    }
    for (int ic = 0; ic < numChars; ic++) if (getSelected(ic)) cD.setSelected(ic - icStart, true);

    return cD;
  }
 /*..........................................    ..................................................*/
 public void setState(int ic, int it, int item, double states) {
   if (!legalValue(ic, states)) {
     return;
   }
   super.setState(ic, it, item, states);
 }