/**
   * Set the layout policy.
   *
   * @param policy policy defining how the layout is computed
   */
  public synchronized void setLayoutPolicy(LayoutPolicy policy) {
    if (policy != layoutPolicy) {
      switch (layoutPolicy) {
        case ComputedInLayoutRunner:
          optLayout.release();
          optLayout = null;
          layoutPipeIn.removeAttributeSink(gg);
          layoutPipeIn = null;
          layout = null;
          break;
        case ComputedAtNewImage:
          gg.removeSink(layout);
          layout.removeAttributeSink(gg);
          layout = null;
          break;
      }

      switch (policy) {
        case ComputedInLayoutRunner:
          layout = Layouts.newLayoutAlgorithm();
          optLayout = new LayoutRunner(gg, layout);
          layoutPipeIn = optLayout.newLayoutPipe();
          layoutPipeIn.addAttributeSink(gg);
          break;
        case ComputedAtNewImage:
          layout = Layouts.newLayoutAlgorithm();
          gg.addSink(layout);
          layout.addAttributeSink(gg);
          break;
      }

      layoutPolicy = policy;
    }
  }
  /**
   * Set the layout policy.
   *
   * @param policy policy defining how the layout is computed
   */
  public synchronized void setLayoutPolicy(LayoutPolicy policy) {
    if (policy != layoutPolicy) {
      switch (layoutPolicy) {
        case COMPUTED_IN_LAYOUT_RUNNER:
          // layout.removeListener(this);
          optLayout.release();
          optLayout = null;
          layoutPipeIn.removeAttributeSink(gg);
          layoutPipeIn = null;
          layout = null;
          break;
        case COMPUTED_ONCE_AT_NEW_IMAGE:
          // layout.removeListener(this);
          gg.removeSink(layout);
          layout.removeAttributeSink(gg);
          layout = null;
          break;
        default:
          break;
      }

      switch (policy) {
        case COMPUTED_IN_LAYOUT_RUNNER:
          layout = Layouts.newLayoutAlgorithm();
          optLayout = new InnerLayoutRunner();
          break;
        case COMPUTED_FULLY_AT_NEW_IMAGE:
        case COMPUTED_ONCE_AT_NEW_IMAGE:
          layout = Layouts.newLayoutAlgorithm();
          gg.addSink(layout);
          layout.addAttributeSink(gg);
          break;
        default:
          break;
      }

      // layout.addListener(this);
      layoutPolicy = policy;
    }
  }