public synchronized void remove() {
   if (evaluatedWatch != null) {
     evaluatedWatch.remove();
   } else {
     w.remove();
   }
 }
 @Override
 public String getType() {
   JPDAWatch evaluatedWatch;
   synchronized (this) {
     evaluatedWatch = this.evaluatedWatch;
   }
   if (evaluatedWatch == null) {
     JPDAWatch[] watchRef = new JPDAWatch[] {null};
     getValue(watchRef); // To init the evaluatedWatch
     evaluatedWatch = watchRef[0];
   }
   if (evaluatedWatch == null) {
     return "";
   }
   return evaluatedWatch.getType();
 }
 public synchronized String getExpression() {
   if (evaluatedWatch != null) {
     return evaluatedWatch.getExpression();
   } else {
     return w.getExpression();
   }
 }
 public synchronized String getExceptionDescription() {
   if (evaluatedWatch != null) {
     return evaluatedWatch.getExceptionDescription();
   } else {
     return null;
   }
 }
 @Override
 public synchronized void setValue(String value) throws InvalidExpressionException {
   if (evaluatedWatch != null) {
     evaluatedWatch.setValue(value);
   } else {
     throw new InvalidExpressionException("Can not set value while evaluating.");
   }
 }
 @Override
 public String getToStringValue() throws InvalidExpressionException {
   if (!w.isEnabled()) {
     return NbBundle.getMessage(WatchesModel.class, "CTL_WatchDisabled");
   }
   JPDAWatch evaluatedWatch;
   synchronized (this) {
     evaluatedWatch = this.evaluatedWatch;
   }
   if (evaluatedWatch == null) {
     JPDAWatch[] watchRef = new JPDAWatch[] {null};
     getValue(watchRef); // To init the evaluatedWatch
     evaluatedWatch = watchRef[0];
   }
   String e = evaluatedWatch.getExceptionDescription();
   if (e != null) {
     return ">" + e + "<"; // NOI18N
   } else {
     return evaluatedWatch.getToStringValue();
   }
 }
    private String getValue(JPDAWatch[] watchRef) {
      if (!w.isEnabled()) {
        return NbBundle.getMessage(WatchesModel.class, "CTL_WatchDisabled");
      }
      synchronized (evaluating) {
        if (evaluating[0]) {
          try {
            evaluating.wait();
          } catch (InterruptedException iex) {
            return null;
          }
        }
        synchronized (this) {
          if (evaluatedWatch != null) {
            if (watchRef != null) watchRef[0] = evaluatedWatch;
            return evaluatedWatch.getValue();
          }
        }
        evaluating[0] = true;
      }

      JPDAWatch jw = null;
      try {
        EvaluatorExpression expr = getParsedExpression();
        if (expr == null) {
          parseExpression(w.getExpression());
          expr = getParsedExpression();
        }
        Value v = debugger.evaluateIn(expr);
        // if (v instanceof ObjectReference)
        //    jw = new JPDAObjectWatchImpl (debugger, w, (ObjectReference) v);
        if (v instanceof PrimitiveValue) {
          JPDAWatchImpl jwi = new JPDAWatchImpl(debugger, w, (PrimitiveValue) v, this);
          jwi.addPropertyChangeListener(this);
          jw = jwi;
        } else { // ObjectReference or VoidValue
          JPDAObjectWatchImpl jwi = new JPDAObjectWatchImpl(debugger, w, v);
          jwi.addPropertyChangeListener(this);
          jw = jwi;
          /* Uncomment if evaluator returns variables with disabled collection
          if (v instanceof ObjectReference) {
              // Returned variable with disabled collection. When not used any more,
              // it's collection must be enabled again.
              try {
                  ObjectReferenceWrapper.enableCollection((ObjectReference) v);
              } catch (Exception ex) {}
          }*/
        }
      } catch (InvalidExpressionException e) {
        JPDAWatchImpl jwi = new JPDAWatchImpl(debugger, w, e, this);
        jwi.addPropertyChangeListener(this);
        jw = jwi;
      } finally {
        setEvaluated(jw);
        if (watchRef != null) watchRef[0] = jw;
        synchronized (evaluating) {
          evaluating[0] = false;
          evaluating.notifyAll();
        }
      }
      // System.out.println("    value = "+jw.getValue());
      return jw.getValue();
    }