/**
   * The constants used in this Content Widget.
   */
  public static interface CwConstants extends Constants {
    String cwCookiesDeleteCookie();

    String cwCookiesDescription();

    String cwCookiesExistingLabel();

    String cwCookiesInvalidCookie();

    String cwCookiesName();

    String cwCookiesNameLabel();

    String cwCookiesSetCookie();

    String cwCookiesValueLabel();
  }

  /**
   * The timeout before a cookie expires, in milliseconds. Current one day.
   */
  private static final int COOKIE_TIMEOUT = 1000 * 60 * 60 * 24;

  /**
   * An instance of the constants.
   */
  private final CwConstants constants;

  /**
   * A {@link TextBox} that holds the name of the cookie.
   */
  private TextBox cookieNameBox = null;

  /**
   * A {@link TextBox} that holds the value of the cookie.
   */
  private TextBox cookieValueBox = null;

  /**
   * The {@link ListBox} containing existing cookies.
   */
  private ListBox existingCookiesBox = null;

  /**
   * Initialize this example.
   */
  @Override
  public Widget onInitialize() {
    // Create the panel used to layout the content
    Grid mainLayout = new Grid(3, 3);

    // Display the existing cookies
    existingCookiesBox = new ListBox();
    Button deleteCookieButton = new Button(constants.cwCookiesDeleteCookie());
    deleteCookieButton.addStyleName("sc-FixedWidthButton");
    mainLayout.setHTML(
        0, 0, "<b>" + constants.cwCookiesExistingLabel() + "</b>");
    mainLayout.setWidget(0, 1, existingCookiesBox);
    mainLayout.setWidget(0, 2, deleteCookieButton);

    // Display the name of the cookie
    cookieNameBox = new TextBox();
    mainLayout.setHTML(1, 0, "<b>" + constants.cwCookiesNameLabel() + "</b>");
    mainLayout.setWidget(1, 1, cookieNameBox);

    // Display the name of the cookie
    cookieValueBox = new TextBox();
    Button setCookieButton = new Button(constants.cwCookiesSetCookie());
    setCookieButton.addStyleName("sc-FixedWidthButton");
    mainLayout.setHTML(2, 0, "<b>" + constants.cwCookiesValueLabel() + "</b>");
    mainLayout.setWidget(2, 1, cookieValueBox);
    mainLayout.setWidget(2, 2, setCookieButton);

    // Add a handler to set the cookie value
    setCookieButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        String name = cookieNameBox.getText();
        String value = cookieValueBox.getText();
        Date expires = new Date((new Date()).getTime() + COOKIE_TIMEOUT);

        // Verify the name is valid
        if (name.length() < 1) {
          Window.alert(constants.cwCookiesInvalidCookie());
          return;
        }

        // Set the cookie value
        Cookies.setCookie(name, value, expires);
        refreshExistingCookies(name);
      }
    });

    // Add a handler to select an existing cookie
    existingCookiesBox.addChangeHandler(new ChangeHandler() {
      public void onChange(ChangeEvent event) {
        updateExstingCookie();
      }
    });

    // Add a handler to delete an existing cookie
    deleteCookieButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        int selectedIndex = existingCookiesBox.getSelectedIndex();
        if (selectedIndex > -1
            && selectedIndex < existingCookiesBox.getItemCount()) {
          String cookieName = existingCookiesBox.getValue(selectedIndex);
          Cookies.removeCookie(cookieName);
          existingCookiesBox.removeItem(selectedIndex);
          updateExstingCookie();
        }
      }
    });

    // Return the main layout
    refreshExistingCookies(null);
    return mainLayout;
  }

  /**
   * Refresh the list of existing cookies.
   *
   * @param selectedCookie the cookie to select by default
   */
  private void refreshExistingCookies(String selectedCookie) {
    // Clear the existing cookies
    existingCookiesBox.clear();

    // Add the cookies
    int selectedIndex = 0;
    Collection<String> cookies = Cookies.getCookieNames();
    for (String cookie : cookies) {
      existingCookiesBox.addItem(cookie);
      if (cookie.equals(selectedCookie)) {
        selectedIndex = existingCookiesBox.getItemCount() - 1;
      }
    }

    // Select the index of the selectedCookie. Use a ScheduledCommand to give
    // the options time to register in Opera.
    final int selectedIndexFinal = selectedIndex;
    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
      public void execute() {
        // Select the default cookie
        if (selectedIndexFinal < existingCookiesBox.getItemCount()) {
          existingCookiesBox.setSelectedIndex(selectedIndexFinal);
        }

        // Display the selected cookie value
        updateExstingCookie();
      }
    });
  }

  /**
   * Retrieve the value of the existing cookie and put it into to value label.
   */
  private void updateExstingCookie() {
    // Cannot update if there are no items
    if (existingCookiesBox.getItemCount() < 1) {
      cookieNameBox.setText("");
      cookieValueBox.setText("");
      return;
    }

    int selectedIndex = existingCookiesBox.getSelectedIndex();
    String cookieName = existingCookiesBox.getValue(selectedIndex);
    String cookieValue = Cookies.getCookie(cookieName);
    cookieNameBox.setText(cookieName);
    cookieValueBox.setText(cookieValue);
  }