public void make() throws RedirectException {
    if (mOwnIdentity == null) {
      throw new RedirectException(logIn);
    }

    makeBreadcrumbs();

    boolean subscribe = mRequest.isPartSet("Subscribe");
    boolean unsubscribe = mRequest.isPartSet("Unsubscribe");

    if ((subscribe ^ unsubscribe) && mRequest.getMethod().equals("POST")) {
      String boardName =
          mRequest.getPartAsStringFailsafe("BoardName", Board.MAX_BOARDNAME_TEXT_LENGTH);

      try {
        MessageManager messageManager = mFreetalk.getMessageManager();

        if (subscribe) {
          SubscribedBoard board = messageManager.subscribeToBoard(mOwnIdentity, boardName);

          HTMLNode successBox =
              addContentBox(l10n().getString("SelectBoardsPage.SubscriptionSucceededBox.Header"));
          l10n()
              .addL10nSubstitution(
                  successBox.addChild("div"),
                  "SelectBoardsPage.SubscriptionSucceededBox.Text",
                  new String[] {"link", "boardname"},
                  new HTMLNode[] {
                    HTMLNode.link(BoardPage.getURI(board)), HTMLNode.text(board.getName())
                  });
        } else if (unsubscribe) {
          messageManager.unsubscribeFromBoard(mOwnIdentity, boardName);

          HTMLNode successBox =
              addContentBox(l10n().getString("SelectBoardsPage.UnsubscriptionSucceededBox.Header"));
          l10n()
              .addL10nSubstitution(
                  successBox.addChild("div"),
                  "SelectBoardsPage.UnsubscriptionSucceededBox.Text",
                  new String[] {"boardname"},
                  new HTMLNode[] {HTMLNode.text(boardName)});
        }
      } catch (Exception e) {
        HTMLNode alertBox =
            addAlertBox(
                subscribe
                    ? l10n().getString("SelectBoardsPage.SubscribeFailed")
                    : l10n().getString("SelectBoardsPage.UnsubscribeFailed"));
        alertBox.addChild("div", e.getMessage());

        Logger.error(this, subscribe ? "subscribe failed" : "unsubscribe failed", e);
      }
    }

    makeBoardsList();
  }
 /** Get the last valid message number. */
 public int lastMessage() {
   try {
     return mBoard.getLastMessageIndex();
   } catch (NoSuchMessageException e) {
     return 0; // TODO: Does NNTP expect this if there are no messages??
   }
 }
  private void makeBoardsList() {
    HTMLNode boardsBox = addContentBox(l10n().getString("SelectBoardsPage.SelectBoardsBox.Header"));

    boardsBox.addChild("p", l10n().getString("SelectBoardsPage.SelectBoardsBox.Text"));

    HTMLNode buttonRow = boardsBox.addChild("div", "class", "button-row");

    HTMLNode buttonDiv = buttonRow.addChild("div", "class", "button-row-button");
    HTMLNode newBoardForm =
        addFormChild(buttonDiv, Freetalk.PLUGIN_URI + "/NewBoard", "NewBoardPage");
    newBoardForm.addChild(
        "input",
        new String[] {"type", "name", "value"},
        new String[] {"hidden", "OwnIdentityID", mOwnIdentity.getID()});
    newBoardForm.addChild(
        "input",
        new String[] {"type", "name", "value"},
        new String[] {"submit", "submit", l10n().getString("SelectBoardsPage.NewBoardButton")});

    buttonDiv = buttonRow.addChild("div", "class", "button-row-button");
    HTMLNode deleteEmptyBoardsForm =
        addFormChild(buttonDiv, Freetalk.PLUGIN_URI + "/DeleteEmptyBoards", "DeleteEmptyBoards");
    deleteEmptyBoardsForm.addChild(
        "input",
        new String[] {"type", "name", "value"},
        new String[] {"hidden", "OwnIdentityID", mOwnIdentity.getID()});
    deleteEmptyBoardsForm.addChild(
        "input",
        new String[] {"type", "name", "value"},
        new String[] {
          "submit",
          "submit",
          l10n().getString("SelectBoardsPage.SelectBoardsBox.DeleteEmptyBoardsButton")
        });

    // Clear margins after button row. TODO: Refactoring: Move to CSS
    boardsBox.addChild("div", "style", "clear: both;");

    HTMLNode boardsTable = boardsBox.addChild("table", "border", "0");
    HTMLNode row = boardsTable.addChild("tr");
    row.addChild("th", l10n().getString("SelectBoardsPage.BoardTableHeader.Language"));
    row.addChild("th", l10n().getString("SelectBoardsPage.BoardTableHeader.Name"));
    row.addChild("th", l10n().getString("SelectBoardsPage.BoardTableHeader.Description"));
    row.addChild("th", l10n().getString("SelectBoardsPage.BoardTableHeader.FirstSeen"));
    row.addChild("th", l10n().getString("SelectBoardsPage.BoardTableHeader.LatestMessage"));
    row.addChild("th", l10n().getString("SelectBoardsPage.BoardTableHeader.Messages"));
    row.addChild("th", l10n().getString("SelectBoardsPage.BoardTableHeader.Subscribe"));
    row.addChild("th", l10n().getString("SelectBoardsPage.BoardTableHeader.Unsubscribe"));

    DateFormat dateFormat = DateFormat.getInstance();

    MessageManager messageManager = mFreetalk.getMessageManager();

    synchronized (messageManager) {
      for (final Board board : messageManager.boardIteratorSortedByName()) {
        row = boardsTable.addChild("tr", "id", board.getName());

        // Language

        row.addChild(
            "td", new String[] {"align"}, new String[] {"left"}, board.getLanguage().referenceName);

        // Name

        HTMLNode nameCell = row.addChild("th", new String[] {"align"}, new String[] {"left"});

        // .addChild(new HTMLNode("a", "href", Freetalk.PLUGIN_URI + "/SubscribeToBoard?identity=" +
        // mOwnIdentity.getID() + "&name=" + board.getName(),
        //		board.getName()));

        // Description
        row.addChild(
            "td",
            new String[] {"align"},
            new String[] {"left"},
            board.getDescription(mOwnIdentity));

        // First seen
        row.addChild(
            "td",
            new String[] {"align"},
            new String[] {"center"},
            dateFormat.format(board.getFirstSeenDate()));

        // Latest message
        HTMLNode latestMessageCell =
            row.addChild("td", new String[] {"align"}, new String[] {"center"});

        // Message count
        HTMLNode messageCountCell =
            row.addChild("td", new String[] {"align"}, new String[] {"center"});

        HTMLNode subscribeCell =
            row.addChild("td", new String[] {"align"}, new String[] {"center"});
        HTMLNode unsubscribeCell =
            row.addChild("td", new String[] {"align"}, new String[] {"center"});

        try {
          SubscribedBoard subscribedBoard =
              messageManager.getSubscription(mOwnIdentity, board.getName());

          // We are subscribed to that board so we can display some more information.

          nameCell.addChild(new HTMLNode("a", "href", BoardPage.getURI(board), board.getName()));

          try {
            latestMessageCell.addChild(
                "#", dateFormat.format(subscribedBoard.getLatestMessage().getMessageDate()));
          } catch (NoSuchMessageException e) {
            latestMessageCell.addChild("#", "-");
          }

          messageCountCell.addChild("#", Integer.toString(subscribedBoard.messageCount()));

          HTMLNode unsubscribeForm =
              addFormChild(
                  unsubscribeCell,
                  Freetalk.PLUGIN_URI + "/SelectBoards" + "#" + board.getName(),
                  "Unsubscribe");
          unsubscribeForm.addChild(
              "input",
              new String[] {"type", "name", "value"},
              new String[] {"hidden", "OwnIdentityID", mOwnIdentity.getID()});
          unsubscribeForm.addChild(
              "input",
              new String[] {"type", "name", "value"},
              new String[] {"hidden", "BoardName", board.getName()});
          unsubscribeForm.addChild(
              "input",
              new String[] {"type", "name", "value"},
              new String[] {
                "submit",
                "Unsubscribe",
                l10n().getString("SelectBoardsPage.BoardTable.UnsubscribeButton")
              });
        } catch (NoSuchBoardException e) {
          // We are not subscribed to that board so we cannot fill all cells with information.

          nameCell.addChild(
              new HTMLNode("a", "href", NotFetchedMessagesPage.getURI(board), board.getName()));

          latestMessageCell.addChild("#", "-");
          messageCountCell.addChild(
              "#",
              l10n().getString("Common.EstimationPrefix")
                  + " "
                  + messageManager.getDownloadableMessageCount(board));

          HTMLNode subscribeForm =
              addFormChild(
                  subscribeCell,
                  Freetalk.PLUGIN_URI + "/SelectBoards" + "#" + board.getName(),
                  "Subscribe");
          subscribeForm.addChild(
              "input",
              new String[] {"type", "name", "value"},
              new String[] {"hidden", "OwnIdentityID", mOwnIdentity.getID()});
          subscribeForm.addChild(
              "input",
              new String[] {"type", "name", "value"},
              new String[] {"hidden", "BoardName", board.getName()});
          subscribeForm.addChild(
              "input",
              new String[] {"type", "name", "value"},
              new String[] {
                "submit",
                "Subscribe",
                l10n().getString("SelectBoardsPage.BoardTable.SubscribeButton")
              });
        }
      }
    }
  }
 /** Estimate number of messages that have been posted. */
 public long messageCount() {
   return mBoard.getAllMessages(false).size();
 }
 /** Get the group name */
 public String getGroupName() {
   return boardToGroupName(mBoard.getName());
 }