private void replyToComment(final Comment parentComment) {
    String replyPromptMessage = "Reply";
    if (parentComment.getAuthor() != null) {
      replyPromptMessage = "Reply To: " + parentComment.getAuthor().getUsername();
    } else if (!StringUtils.isEmpty(parentComment.getEmail())) {
      replyPromptMessage = "Reply To: " + parentComment.getEmail();
    }
    PromptDialogBox dialog =
        new PromptDialogBox(replyPromptMessage, "Submit", null, "Cancel", false, true);
    dialog.setAllowKeyboardEvents(false);
    VerticalPanel replyPanel = new VerticalPanel();

    final TextArea textArea = new TextArea();
    textArea.setCharacterWidth(60);
    textArea.setVisibleLines(4);
    final TextBox emailTextBox = new TextBox();
    if (AuthenticationHandler.getInstance().getUser() == null) {
      replyPanel.add(new Label("Email:"));
      replyPanel.add(emailTextBox);
    }
    replyPanel.add(textArea);

    dialog.setFocusWidget(textArea);
    dialog.setContent(replyPanel);
    dialog.setValidatorCallback(
        new IDialogValidatorCallback() {
          public boolean validate() {
            if (textArea.getText() == null || "".equals(textArea.getText())) {
              MessageDialogBox dialog =
                  new MessageDialogBox("Error", "Comment is blank.", false, true, true);
              dialog.center();
              return false;
            }
            return true;
          }
        });
    dialog.setCallback(
        new IDialogCallback() {
          public void okPressed() {
            Comment newComment = new Comment();
            newComment.setGlobalRead(true);
            newComment.setOwner(permissibleObject.getOwner());
            newComment.setAuthor(AuthenticationHandler.getInstance().getUser());
            newComment.setComment(textArea.getText());
            newComment.setParent(permissibleObject);
            newComment.setParentComment(parentComment);
            newComment.setEmail(emailTextBox.getText());
            submitComment(newComment);
          }

          public void cancelPressed() {}
        });
    dialog.center();
  }
  private void loadCommentWidget(final boolean forceOpen) {
    clear();
    if (permissibleObject.isAllowComments()) {

      String fileName = permissibleObject.getName();
      final DisclosurePanel commentDisclosurePanel =
          new DisclosurePanel("View comments (" + numComments + ") for " + fileName);

      VerticalPanel commentsPanel = new VerticalPanel();
      commentsPanel.setSpacing(0);
      if (numComments > 0) {
        commentsPanel.setStyleName("commentsPanel");
      }
      commentsPanel.setWidth("100%");

      int renderedComments = 0;
      boolean userCanManage =
          AuthenticationHandler.getInstance().getUser() != null
              && (AuthenticationHandler.getInstance().getUser().isAdministrator()
                  || AuthenticationHandler.getInstance()
                      .getUser()
                      .equals(permissibleObject.getOwner()));
      List<PermissibleObject> sortedComments = new ArrayList<PermissibleObject>();
      if (comments != null) {
        sortedComments.addAll(comments);
      }
      if (!flatten) {
        sortedComments = sortComments(sortedComments);
      }

      for (PermissibleObject obj : sortedComments) {
        final Comment comment = (Comment) obj;
        int commentDepth = getCommentDepth(comment);

        int maxDepth =
            Integer.parseInt(
                maxCommentDepthListBox.getValue(maxCommentDepthListBox.getSelectedIndex()));
        if (commentDepth >= maxDepth) {
          continue;
        }

        boolean userIsAuthorOfComment =
            AuthenticationHandler.getInstance().getUser() != null
                && comment.getAuthor() != null
                && comment.getAuthor().equals(AuthenticationHandler.getInstance().getUser());

        if (userCanManage || userIsAuthorOfComment || comment.isApproved()) {

          FlexTable commentHeaderPanel = new FlexTable();
          commentHeaderPanel.setCellPadding(0);
          commentHeaderPanel.setCellSpacing(0);
          commentHeaderPanel.setStyleName("commentHeader");
          commentHeaderPanel.setWidth("100%");

          String authorLabelString =
              comment.getAuthor() == null ? comment.getEmail() : comment.getAuthor().getUsername();
          if (comment.getAuthor() != null
              && comment.getAuthor().getFirstname() != null
              && !"".equals(comment.getAuthor().getFirstname())) {
            authorLabelString += " (" + comment.getAuthor().getFirstname();
            if (comment.getAuthor() != null
                && comment.getAuthor().getLastname() != null
                && !"".equals(comment.getAuthor().getLastname())) {
              authorLabelString += " " + comment.getAuthor().getLastname() + ")";
            } else {
              authorLabelString += ")";
            }
          }

          Image replyCommentImage = new Image();
          replyCommentImage.setResource(BaseImageBundle.images.reply());
          replyCommentImage.setStyleName("commentActionButton");
          replyCommentImage.setTitle("Reply to this comment");
          replyCommentImage.addClickHandler(
              new ClickHandler() {

                public void onClick(ClickEvent event) {
                  replyToComment(comment);
                }
              });
          int columnIndex = 0;
          commentHeaderPanel.setWidget(0, columnIndex, replyCommentImage);
          commentHeaderPanel
              .getFlexCellFormatter()
              .setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_LEFT);
          columnIndex++;

          Label authorLabel = new Label(authorLabelString, false);
          commentHeaderPanel.setWidget(0, columnIndex, authorLabel);
          commentHeaderPanel
              .getFlexCellFormatter()
              .setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_LEFT);
          columnIndex++;
          commentHeaderPanel.setWidget(0, columnIndex, new Label());
          commentHeaderPanel.getFlexCellFormatter().setWidth(0, columnIndex, "100%");
          commentHeaderPanel
              .getFlexCellFormatter()
              .setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_RIGHT);
          columnIndex++;
          Label dateLabel = new Label(new Date(comment.getCommentDate()).toLocaleString(), false);
          commentHeaderPanel.setWidget(0, columnIndex, dateLabel);
          if (!userCanManage && !userIsAuthorOfComment) {
            DOM.setStyleAttribute(dateLabel.getElement(), "padding", "0 5px 0 0");
          }
          commentHeaderPanel
              .getFlexCellFormatter()
              .setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_RIGHT);

          columnIndex++;
          if (userCanManage || userIsAuthorOfComment) {
            if (userCanManage && !comment.isApproved()) {
              final Image approveCommentImage = new Image();
              approveCommentImage.setResource(BaseImageBundle.images.approve());
              approveCommentImage.setStyleName("commentActionButton");
              approveCommentImage.setTitle("Approve comment");
              approveCommentImage.addClickHandler(
                  new ClickHandler() {

                    public void onClick(ClickEvent event) {
                      workingOnComment = comment;
                      approveComment(comment);
                    }
                  });
              commentHeaderPanel.setWidget(0, columnIndex, approveCommentImage);
              commentHeaderPanel
                  .getFlexCellFormatter()
                  .setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_RIGHT);
              columnIndex++;
            } else {
              // put 16x16 spacer here for alignment
              final Image approveSpacerImage = new Image();
              approveSpacerImage.setResource(BaseImageBundle.images.empty16x16());
              approveSpacerImage.setStyleName("commentActionButton");
              commentHeaderPanel.setWidget(0, columnIndex, approveSpacerImage);
              commentHeaderPanel
                  .getFlexCellFormatter()
                  .setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_RIGHT);
              columnIndex++;
            }
            Image deleteCommentImage = new Image();
            deleteCommentImage.setResource(BaseImageBundle.images.delete());
            deleteCommentImage.setStyleName("commentActionButton");
            deleteCommentImage.setTitle("Remove comment");
            deleteCommentImage.addClickHandler(
                new ClickHandler() {

                  public void onClick(ClickEvent event) {
                    IDialogCallback callback =
                        new IDialogCallback() {

                          public void cancelPressed() {}

                          public void okPressed() {
                            deleteComment(comment);
                          }
                        };
                    PromptDialogBox dialogBox =
                        new PromptDialogBox("Question", "Yes", null, "No", false, true);
                    dialogBox.setContent(
                        new Label(
                            "Delete comment by "
                                + (comment.getAuthor() == null
                                    ? comment.getEmail()
                                    : comment.getAuthor().getUsername())
                                + "?"));
                    dialogBox.setCallback(callback);
                    dialogBox.center();
                  }
                });
            commentHeaderPanel.setWidget(0, columnIndex, deleteCommentImage);
            commentHeaderPanel
                .getFlexCellFormatter()
                .setHorizontalAlignment(0, columnIndex, HasHorizontalAlignment.ALIGN_RIGHT);
            columnIndex++;
          }

          if (commentDepth > 0) {
            HorizontalPanel commentHeaderPanelWrapper = new HorizontalPanel();
            commentHeaderPanelWrapper.setWidth("100%");
            Label spacerLabel = new Label();
            commentHeaderPanelWrapper.add(spacerLabel);
            if (!flatten) {
              commentHeaderPanelWrapper.setCellWidth(spacerLabel, (commentDepth * 20) + "px");
            }
            commentHeaderPanelWrapper.add(commentHeaderPanel);
            commentsPanel.add(commentHeaderPanelWrapper);
          } else {
            commentsPanel.add(commentHeaderPanel);
          }

          // Label commentLabel = new Label(comment.getId() + " " + comment.getComment(), true);
          Label commentLabel = new Label(comment.getComment(), true);
          if (comment.isApproved()) {
            commentLabel.setStyleName("comment");
          } else if (userCanManage || userIsAuthorOfComment) {
            commentLabel.setStyleName("commentAwaitingApproval");
          }

          if (commentDepth > 0) {
            HorizontalPanel commentHeaderPanelWrapper = new HorizontalPanel();
            commentHeaderPanelWrapper.setWidth("100%");
            Label spacerLabel = new Label();
            commentHeaderPanelWrapper.add(spacerLabel);
            if (!flatten) {
              commentHeaderPanelWrapper.setCellWidth(spacerLabel, (commentDepth * 20) + "px");
            }
            commentHeaderPanelWrapper.add(commentLabel);
            commentsPanel.add(commentHeaderPanelWrapper);
          } else {
            commentsPanel.add(commentLabel);
          }
          renderedComments++;
        }
      }

      final FlexTable mainPanel = new FlexTable();
      mainPanel.setWidth("100%");
      int row = 0;
      if (paginate) {
        mainPanel.setWidget(row, 0, createButtonPanel(mainPanel, forceOpen));
        mainPanel
            .getCellFormatter()
            .setHorizontalAlignment(row++, 0, HasHorizontalAlignment.ALIGN_LEFT);
      }
      mainPanel.setWidget(row, 0, commentsPanel);
      mainPanel.getCellFormatter().setWidth(row++, 0, "100%");

      commentDisclosurePanel.setContent(mainPanel);
      commentDisclosurePanel.setOpen(renderedComments == 0 || forceOpen);
      commentDisclosurePanel.setWidth("100%");
      add(createCommentPostPanel());
      add(commentDisclosurePanel);
    }
    if (layoutCallback != null) {
      layoutCallback.layoutComplete();
    }
  }