/**
   * Creates a wave panel.
   *
   * @param views view bundle
   * @param panelDom element in the DOM on which to build the wave panel
   * @param container panel to adopt the wave panel's widget, or {@code null} for the wave panel to
   *     be a root widget
   */
  public static WavePanelImpl create(
      DomAsViewProvider views, Element panelDom, LogicalPanel container) {
    Preconditions.checkArgument(panelDom != null);
    EventDispatcherPanel events =
        (container != null)
            ? EventDispatcherPanel.inGwtContext(panelDom, container)
            : EventDispatcherPanel.of(panelDom);
    WavePanelImpl panel = new WavePanelImpl(views, events);

    // Existing content?
    Element frameDom = panelDom.getFirstChildElement();
    if (frameDom != null) {
      panel.init(frameDom);
    }
    return panel;
  }
  public void init(Element main) {
    Preconditions.checkState(!initialized);

    boolean fireEvent; // true if onInit should be fired before exiting.
    if (main != null) {
      panel.getElement().appendChild(main);
      this.main = views.asTopConversation(main);
      fireEvent = true;
    } else {
      // Render empty message.
      panel.getElement().setInnerHTML("No conversations in this wave.");
      fireEvent = false;
    }
    initialized = true;

    if (fireEvent) {
      fireOnInit();
    }
  }
  public void reset() {
    Preconditions.checkState(initialized);

    boolean fireEvent; // true if onInit should be fired before exiting.
    initialized = false;
    if (main != null) {
      main.remove();
      main = null;
      fireEvent = true;
    } else {
      panel.getElement().setInnerHTML("");
      fireEvent = false;
    }

    if (fireEvent) {
      fireOnReset();
    }
  }
 /** Destroys this wave panel, releasing its resources. */
 public void destroy() {
   panel.removeFromParent();
 }