/** Updates this cell. */
 protected void updateCellValues() {
   if (getColumn() == null) {
     LogUtils.debug(this, "cell disposed! @" + hashCode());
     return;
   }
   IManagerRunnable.Factory.asyncExec(
       "update",
       this,
       new Runnable() {
         @Override
         public void run() {
           updateCellValuesDelayed();
         }
       });
 }
  /**
   * Checks if any current {@link IScriptDependency} match the specified notification.
   *
   * <p>If one does match, all associated expressions are re-evaluated.
   *
   * @param msg the notification to check
   */
  protected void checkChangedDependencies(Notification msg) {
    final EList<IScriptDependency> dList = getDependencies().get(msg.getNotifier());

    /*
     * Should probably never happen!
     */
    if (dList == null) return;

    for (final IScriptDependency d : dList) {
      if (d.getFeature() != msg.getFeature()) {
        continue;
      }

      if (d.getIndex() != -1) {
        if (d.getIndex() != msg.getPosition()) {
          continue;
        }
      }

      if (d.getKey() != null) {
        // TODO
        LogUtils.debug(this, "key=" + d.getKey() + "\nmsg=" + ToStringUtils.toString(msg));
      }

      /*
       * We have a match...
       */
      for (final IScriptExpression e : d.getExpressions()) {
        IManagerRunnable.Factory.asyncExec(
            "evaluate",
            e,
            new Runnable() {
              @Override
              public void run() {
                e.evaluate();
              }
            });
      }
    }
  }
  /**
   * Checks if the current state have changed, and reports these.
   *
   * @param event the current event
   * @return the resulting map
   */
  public Map<String, Object> reportSourceChanges(Event event) {
    if (Activator.getDefault().TRACE_SOURCE_PROVIDER_VERBOSE
        && Activator.getDefault().TRACE_EVENTS_SWT) {
      LogUtils.debug(
          this, (event == myPreviousValueEvent ? "REPLAY " : "") + TSSWTUtils.toString(event));
    }

    /*
     * If the event is FocusIn for the very same widget as last time, but with x,y=0,0, then...
     * ignore it... It is seen whenever the current shell is send to front.
     */
    if (event.type == SWT.FocusIn && event.widget == myLastWidget && event.x == 0 && event.y == 0)
      return myCurrentState;

    /*
     * Ignore all key up events, except those that navigate...
     */
    // if (event.type == SWT.KeyUp && (SWT.KEYCODE_BIT & event.keyCode) == 0) {
    // return myOldState;
    // }

    final Map<String, Object> newState = getCurrentState(event);
    myLastWidget = event.widget;

    /*
     * Update the current state with changes - keeping them in newState as well.
     */
    for (final Iterator<Map.Entry<String, Object>> is = newState.entrySet().iterator();
        is.hasNext(); ) {
      final Map.Entry<String, Object> i = is.next();
      final String s = i.getKey();
      final Object n = i.getValue();

      final Object o = myCurrentState.get(s);
      if (BasicUtils.equals(n, o)) {
        is.remove();
      } else {
        myCurrentState.put(s, n);
      }
    }

    if (!newState.isEmpty()) {
      /*
       * Reset the property testers as well, when any of the values changes
       */
      newState.put(Constants.PREFIX + Constants.PROPERTY_CAN_DELETE, true);
      newState.put(Constants.PREFIX + Constants.PROPERTY_CAN_DELETE_SELECTED_OBJECTS, true);

      if (Activator.getDefault().TRACE_SOURCE_PROVIDER) {
        final StringBuilder sb = new StringBuilder("Binding sources change(" + myLastBinding + ")");
        for (final Map.Entry<String, Object> i : newState.entrySet()) {
          final String s = i.getKey();
          sb.append("\n  ").append(s).append('=');
          final Object v = i.getValue();
          if (v == null) {
            sb.append("<null>");
          } else if (v == IEvaluationContext.UNDEFINED_VARIABLE) {
            sb.append("<undef>");
          } else {
            sb.append('\'')
                .append(v.toString())
                .append('\'')
                .append(" [")
                .append(ClassUtils.getLastClassName(v))
                .append(']');
          }
        }
        LogUtils.debug(this, sb.toString());
      }

      fireSourceChanged(ISources.ACTIVE_CURRENT_SELECTION, newState);

      /*
       * TODO: describe why
       *
       * TODO: only when changing?
       */
      final Object activeBindingObject = myCurrentState.get(Constants.SOURCES_ACTIVE_BINDING);
      if (activeBindingObject instanceof IValueBinding) {
        final IValueBinding vb = (IValueBinding) activeBindingObject;
        IManagerRunnable.Factory.asyncExec(
            "update",
            vb,
            new Runnable() {
              @Override
              public void run() {
                if (vb.isDisposed()) return;
                vb.updateBinding();
              }
            });
      }

      /*
       * And lastly, update the active contexts
       */
      handleContextChanges(myCurrentState);
    }

    return myCurrentState;
  }