public void checkDirect() throws VisADException, RemoteException {
    // realCheckDirect();
    //
    // must customize
    setIsDirectManipulation(false);

    DisplayImpl display = getDisplay();
    link = getLinks()[0];
    ref = link.getDataReference();
    type = link.getType();
    if (!(type instanceof TupleType) || !((TupleType) type).getFlat()) {
      whyNotDirect = notFlatTupleType;
      return;
    }
    flowToComponent = new int[] {-1, -1, -1};
    directMap = new ScalarMap[] {null, null, null};
    shadow = (ShadowTupleType) link.getShadow().getAdaptedShadowType();
    DisplayTupleType[] tuples = {null};
    whyNotDirect = findFlow(shadow, display, tuples, flowToComponent);
    if (whyNotDirect != null) return;
    if (coord == null) {
      if (tuples[0] == null || flowToComponent[0] < 0 || flowToComponent[1] < 0) {
        whyNotDirect = noFlow;
        return;
      }
    } else {
      if (tuples[0] == null || flowToComponent[1] < 0 || flowToComponent[2] < 0) {
        whyNotDirect = noFlow;
        return;
      }
    }

    ShadowRealType[] components = shadow.getRealComponents();
    for (int i = 0; i < components.length; i++) {
      DisplayTupleType spatial_tuple = components[i].getDisplaySpatialTuple();
      if (spatial_tuple != null && !Display.DisplaySpatialCartesianTuple.equals(spatial_tuple)) {
        whyNotDirect = nonCartesian;
        return;
      }
    }

    // needs more, will find out when we write drag_direct
    setIsDirectManipulation(true);
  }