public SessionComparisonPanel(
      Set<SessionDataDto> chosenSessions,
      int width,
      WebClientProperties webClientProperties,
      DateTimeFormat dateFormatter) {

    this.dateFormatter = dateFormatter;
    setWidth(ONE_HUNDRED_PERCENTS);
    setHeight(ONE_HUNDRED_PERCENTS);
    this.chosenSessions = chosenSessions;
    this.webClientProperties = webClientProperties;
    init(this.chosenSessions, width);
    userCommentBox = new UserCommentBox(webClientProperties.getUserCommentMaxLength());
    userCommentBox.setTreeGrid(treeGrid);
    tagBox = new TagBox();
    tagBox.setTreeGrid(treeGrid);
    if (webClientProperties.isTagsStoreAvailable()) allTags();
  }
  public void addSessionInfo() {
    TreeItem sessionInfo = new TreeItem(SESSION_INFO_ID);
    sessionInfo.put(NAME, "Session Info");
    treeStore.insert(0, sessionInfo);

    String tagsStr = "";
    TreeItem itemActiveKernels = new TreeItem(ACTIVE_KERNELS);
    TreeItem itemTaskExecuted = new TreeItem(TASKS_EXECUTED);
    TreeItem itemTaskFailed = new TreeItem(TASKS_FAILED);
    TreeItem itemDateStart = new TreeItem(START_DATE);
    TreeItem itemDateEnd = new TreeItem(END_DATE);
    TreeItem itemComment = new TreeItem(COMMENT);
    TreeItem itemUserComment = new TreeItem(USER_COMMENT);
    TreeItem itemTags = new TreeItem(SESSION_TAGS);

    itemActiveKernels.put(NAME, ACTIVE_KERNELS);
    itemTaskExecuted.put(NAME, TASKS_EXECUTED);
    itemTaskFailed.put(NAME, TASKS_FAILED);
    itemDateStart.put(NAME, START_DATE);
    itemDateEnd.put(NAME, END_DATE);
    itemComment.put(NAME, COMMENT);
    if (webClientProperties.isUserCommentStoreAvailable()) itemUserComment.put(NAME, USER_COMMENT);
    if (webClientProperties.isTagsStoreAvailable()) itemTags.put(NAME, SESSION_TAGS);

    for (SessionDataDto session : chosenSessions) {
      itemActiveKernels.put(
          SESSION_HEADER + session.getSessionId(), session.getActiveKernelsCount() + "");
      itemTaskExecuted.put(
          SESSION_HEADER + session.getSessionId(), session.getTasksExecuted() + "");
      itemTaskFailed.put(SESSION_HEADER + session.getSessionId(), session.getTasksFailed() + "");
      itemDateStart.put(
          SESSION_HEADER + session.getSessionId(), dateFormatter.format(session.getStartDate()));
      itemDateEnd.put(
          SESSION_HEADER + session.getSessionId(), dateFormatter.format(session.getEndDate()));
      itemComment.put(SESSION_HEADER + session.getSessionId(), session.getComment());
      if (webClientProperties.isUserCommentStoreAvailable()) {
        String userComment = session.getUserComment() == null ? "" : session.getUserComment();
        itemUserComment.put(SESSION_HEADER + session.getSessionId(), userComment);
      }
      if (webClientProperties.isTagsStoreAvailable()) {
        for (int i = 0; i < session.getTags().size(); i++) {
          if (i == session.getTags().size() - 1) tagsStr += session.getTags().get(i).getName();
          else tagsStr += session.getTags().get(i).getName() + ", ";
        }
        itemTags.put(SESSION_HEADER + session.getSessionId(), tagsStr);
        tagsStr = "";
      }
    }
    treeStore.add(sessionInfo, itemComment);
    if (webClientProperties.isUserCommentStoreAvailable())
      treeStore.add(sessionInfo, itemUserComment);
    if (webClientProperties.isTagsStoreAvailable()) treeStore.add(sessionInfo, itemTags);
    treeStore.add(sessionInfo, itemDateStart);
    treeStore.add(sessionInfo, itemDateEnd);

    treeStore.add(sessionInfo, itemActiveKernels);
    treeStore.add(sessionInfo, itemTaskExecuted);
    treeStore.add(sessionInfo, itemTaskFailed);
  }
 private String getTestItemName(TaskDataDto tdd) {
   if (webClientProperties.isShowOnlyMatchedTests()) return tdd.getTaskName();
   else return tdd.getTaskName() + " from sessions: " + tdd.getSessionIds();
 }
  private void init(Set<SessionDataDto> chosenSessions, int width) {

    int colWidth = calculateWidth(chosenSessions.size(), width);

    treeStore.clear();
    List<ColumnConfig<TreeItem, ?>> columns = new ArrayList<ColumnConfig<TreeItem, ?>>();

    // sort sessions by number sessionId
    SortedSet<SessionDataDto> sortedSet =
        new TreeSet<SessionDataDto>(
            new Comparator<SessionDataDto>() {
              @Override
              public int compare(SessionDataDto o, SessionDataDto o2) {
                return (Long.parseLong(o.getSessionId()) - Long.parseLong(o2.getSessionId())) > 0
                    ? 1
                    : -1;
              }
            });
    sortedSet.addAll(chosenSessions);

    ColumnConfig<TreeItem, String> nameColumn =
        new ColumnConfig<TreeItem, String>(
            new MapValueProvider(NAME), (int) (colWidth * METRIC_COLUMN_WIDTH_FACTOR));
    nameColumn.setHeader(METRIC);
    nameColumn.setSortable(false);
    nameColumn.setMenuDisabled(true);
    columns.add(nameColumn);

    for (SessionDataDto session : sortedSet) {
      ColumnConfig<TreeItem, String> column =
          new ColumnConfig<TreeItem, String>(
              new MapValueProvider(SESSION_HEADER + session.getSessionId()));
      column.setHeader(SESSION_HEADER + session.getSessionId());
      column.setWidth(colWidth);
      column.setSortable(false);
      column.setCell(
          new AbstractCell<String>() {
            @Override
            public void render(Context context, String value, SafeHtmlBuilder sb) {
              if (value != null) {
                sb.appendHtmlConstant(value);
              }
            }
          });
      column.setMenuDisabled(true);

      column.setColumnTextStyle(
          new SafeStyles() {
            @Override
            public String asString() {
              return WHITE_SPACE_NORMAL;
            }
          });

      columns.add(column);
    }

    ColumnModel<TreeItem> cm = new ColumnModel<TreeItem>(columns);

    treeGrid = new NoIconsTreeGrid(treeStore, cm, nameColumn);

    treeGrid.addBeforeCollapseHandler(
        new BeforeCollapseItemEvent.BeforeCollapseItemHandler<TreeItem>() {
          @Override
          public void onBeforeCollapse(BeforeCollapseItemEvent<TreeItem> event) {
            event.setCancelled(true);
          }
        });

    treeGrid.setAutoExpand(true);
    treeGrid.getView().setStripeRows(true);
    treeGrid.setMinColumnWidth(MIN_COLUMN_WIDTH);
    treeGrid.setAllowTextSelection(true);
    treeGrid.getView().setForceFit(true);

    treeStore.addStoreAddHandler(
        new StoreAddEvent.StoreAddHandler<TreeItem>() {
          @Override
          public void onAdd(StoreAddEvent<TreeItem> event) {
            for (TreeItem item : event.getItems()) {
              treeGrid.setExpanded(item, true);
            }
          }
        });

    if (webClientProperties.isUserCommentEditAvailable()) {
      treeGrid.addCellDoubleClickHandler(
          new CellDoubleClickEvent.CellDoubleClickHandler() {
            @Override
            public void onCellClick(CellDoubleClickEvent event) {
              TreeItem item =
                  treeGrid.findNode(treeGrid.getTreeView().getRow(event.getRowIndex())).getModel();
              if (item.getKey().equals(USER_COMMENT) && event.getCellIndex() > 0) {
                SessionDataDto currentSession = defineCurrentSession(event);
                userCommentBox.popUp(
                    currentSession, item.get(SESSION_HEADER + currentSession.getSessionId()), item);
              }
            }
          });
    }

    if (webClientProperties.isTagsAvailable()) {
      treeGrid.addCellDoubleClickHandler(
          new CellDoubleClickEvent.CellDoubleClickHandler() {
            @Override
            public void onCellClick(CellDoubleClickEvent event) {
              TreeItem item =
                  treeGrid.findNode(treeGrid.getTreeView().getRow(event.getRowIndex())).getModel();
              if (item.getKey().equals(SESSION_TAGS) && event.getCellIndex() > 0) {
                SessionDataDto currentSession = defineCurrentSession(event);
                if (allTagsLoadComplete) tagBox.popUpForEdit(currentSession, item, allTags);
              }
            }
          });
    }

    add(treeGrid);
  }