@Override
  public void endContainerLayout(C container, M metawidget) {

    // End hanging layouts

    State<C> state = getState(container, metawidget);

    if (state.currentSectionWidget != null) {
      super.endContainerLayout(state.currentSectionWidget, metawidget);
    }

    super.endContainerLayout(container, metawidget);
    state.currentSection = null;
    state.currentSectionWidget = null;
  }
  @Override
  public void startContainerLayout(C container, M metawidget) {

    super.startContainerLayout(container, metawidget);

    State state = getState(container, metawidget);
    state.currentSections = null;
  }
  @Override
  public void layoutWidget(
      W widget, String elementName, Map<String, String> attributes, C container, M metawidget) {

    // Stay where we are?
    //
    // Note: Ignore empty stubs. Do not create a new section in case it ends up being empty

    String section = stripSection(attributes);
    State<C> state = getState(container, metawidget);

    if (isEmptyStub(widget) || section == null || section.equals(state.currentSection)) {
      if (state.currentSectionWidget == null) {
        super.layoutWidget(widget, elementName, attributes, container, metawidget);
      } else {
        super.layoutWidget(widget, elementName, attributes, state.currentSectionWidget, metawidget);
      }

      return;
    }

    // End current section

    C previousSectionWidget = state.currentSectionWidget;

    if (state.currentSectionWidget != null) {
      super.endContainerLayout(state.currentSectionWidget, metawidget);
    }

    state.currentSection = section;
    state.currentSectionWidget = null;

    // No new section?

    if ("".equals(section)) {
      super.layoutWidget(widget, elementName, attributes, container, metawidget);
      return;
    }

    // Start new section

    state.currentSectionWidget =
        createSectionWidget(previousSectionWidget, attributes, container, metawidget);
    super.startContainerLayout(state.currentSectionWidget, metawidget);

    // Add component to new section

    super.layoutWidget(widget, elementName, attributes, state.currentSectionWidget, metawidget);
  }
  @Override
  public void layoutWidget(
      W widget, String elementName, Map<String, String> attributes, C container, M metawidget) {

    // If our delegate is itself a NestedSectionLayoutDecorator, strip the section

    State state = getState(container, metawidget);

    if (getDelegate() instanceof NestedSectionLayoutDecorator<?, ?, ?>) {

      String section = stripSection(attributes);

      // Stay where we are?
      //
      // Note: Ignore empty stubs. Do not create a new section in case it ends up being empty

      if (isIgnored(widget)
          || section == null
          || (state.currentSections != null && section.equals(state.currentSections[0]))) {
        super.layoutWidget(widget, elementName, attributes, container, metawidget);
        return;
      }

      // End nested LayoutDecorator's current section

      if (state.currentSections != null && !section.equals(state.currentSections[0])) {
        super.endContainerLayout(container, metawidget);
      }

      state.currentSections = new String[] {section};

      // Add a heading

      if (!"".equals(section)) {
        addSectionWidget(section, 0, container, metawidget);
      }
    } else {

      String[] sections = getSections(attributes);

      // Stay where we are?
      //
      // Note: Ignore empty stubs. Do not create a new section in case it ends up being empty

      if (isIgnored(widget)
          || sections.length == 0
          || Arrays.equals(sections, state.currentSections)) {
        super.layoutWidget(widget, elementName, attributes, container, metawidget);
        return;
      }

      // For each of the new sections...

      for (int level = 0; level < sections.length; level++) {
        String section = sections[level];

        // ...that are different from our current...

        if ("".equals(section)) {
          continue;
        }

        if (state.currentSections != null
            && level < state.currentSections.length
            && section.equals(state.currentSections[level])) {
          continue;
        }

        // ...add a heading
        //
        // Note: we cannot stop/start the delegate layout here. It is tempting, but remember
        // addSectionWidget needs to use the delegate. If you stop/add section heading/start
        // the delegate, who is laying out the section heading?

        addSectionWidget(section, level, container, metawidget);
      }

      state.currentSections = sections;
    }

    // Add component as normal

    super.layoutWidget(widget, elementName, attributes, container, metawidget);
  }
 /**
  * @param v
  * @param location
  * @see edu.uci.ics.jung.algorithms.layout.Layout#setLocation(java.lang.Object,
  *     java.awt.geom.Point2D)
  */
 @Override
 public void setLocation(V v, Point2D location) {
   super.setLocation(v, location);
   fireStateChanged();
 }
 /** @see edu.uci.ics.jung.algorithms.layout.Layout#initialize() */
 @Override
 public void initialize() {
   super.initialize();
   fireStateChanged();
 }
 /** @see edu.uci.ics.jung.algorithms.layout.Layout#step() */
 @Override
 public void step() {
   super.step();
   fireStateChanged();
 }