You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by dp...@apache.org on 2019/06/09 19:27:44 UTC

[ignite-teamcity-bot] branch master updated: TC Bot engine module introduced: tracked branch processor moved to engine

This is an automated email from the ASF dual-hosted git repository.

dpavlov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git


The following commit(s) were added to refs/heads/master by this push:
     new c8021f4  TC Bot engine module introduced: tracked branch processor moved to engine
c8021f4 is described below

commit c8021f443a654b3269175c036c316decdea90235
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Sun Jun 9 22:27:38 2019 +0300

    TC Bot engine module introduced: tracked branch processor moved to engine
---
 .../org/apache/ignite/ci/di/IgniteTcBotModule.java |  3 +-
 .../ignite/ci/jira/ignited/JiraTicketSync.java     |  2 +-
 .../ci/tcbot/TcBotBusinessServicesModule.java      |  2 +-
 .../ci/tcbot/builds/CompareBuildsService.java      |  2 +-
 .../ignite/ci/tcbot/chain/PrChainsProcessor.java   | 88 ++++++++++++++++------
 .../ignite/ci/tcbot/issue/IssueDetector.java       | 34 +++++----
 .../ci/tcbot/trends/MasterTrendsService.java       |  2 +-
 .../tcbot/visa/TcBotTriggerAndSignOffService.java  | 22 +++---
 .../java/org/apache/ignite/ci/web/CtxListener.java |  1 +
 .../org/apache/ignite/ci/web/rest/GetBuildLog.java | 14 ++--
 .../ignite/ci/web/rest/GetChainResultsAsHtml.java  | 26 +++----
 .../ci/web/rest/build/GetBuildTestFailures.java    | 22 +++---
 .../apache/ignite/ci/web/rest/issues/TcIssues.java |  2 +-
 .../long_running/BuildsLongRunningTestsReport.java |  6 +-
 .../ignite/ci/web/rest/pr/GetPrTestFailures.java   | 10 +--
 .../rest/tracked/GetTrackedBranchTestResults.java  | 26 +++----
 .../org/apache/ignite/ci/di/DiContextTest.java     |  4 +-
 .../ci/tcbot/chain/BuildChainProcessorTest.java    |  6 +-
 .../ci/tcbot/chain/PrChainsProcessorTest.java      | 24 +++---
 .../ci/tcbot/chain/TrackedBranchProcessorTest.java | 26 ++++---
 .../apache/ignite/tcbot/common}/util/UrlUtil.java  |  2 +-
 .../tcbot/engine}/chain/BuildChainProcessor.java   | 34 ++++-----
 .../ignite/tcbot/engine}/issue/EventTemplate.java  |  2 +-
 .../ignite/tcbot/engine}/issue/EventTemplates.java |  2 +-
 .../ignite/tcbot/engine/pool}/TcUpdatePool.java    |  2 +-
 .../tracked}/TrackedBranchChainsProcessor.java     | 33 ++++----
 .../org/apache/ignite/tcbot/engine/ui/BotUrls.java | 20 ++---
 .../apache/ignite/tcbot/engine/ui/DsChainUi.java   | 81 +++++---------------
 .../ignite/tcbot/engine/ui/DsHistoryStatUi.java    |  6 +-
 .../ignite/tcbot/engine/ui/DsProblemRef.java       |  6 +-
 .../apache/ignite/tcbot/engine/ui/DsSuiteUi.java   | 82 ++++++++++----------
 .../apache/ignite/tcbot/engine/ui/DsSummaryUi.java | 19 +++--
 .../ignite/tcbot/engine/ui/DsTestFailureUi.java    | 31 ++++----
 .../ignite/tcbot/engine/ui/DsTestHistoryUi.java    | 10 +--
 .../apache/ignite/tcbot/engine/ui/LrTestUi.java    |  7 +-
 .../tcbot/engine/ui/LrTestsFullSummaryUi.java      |  8 +-
 .../tcbot/engine/ui/LrTestsSuiteSummaryUi.java     |  8 +-
 .../org/apache/ignite/tcbot/engine/ui/README.md    |  7 ++
 .../apache/ignite/tcbot/engine/ui}/UpdateInfo.java | 17 ++---
 39 files changed, 349 insertions(+), 350 deletions(-)

diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java
index 840c352..bcbc2e7 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/di/IgniteTcBotModule.java
@@ -39,9 +39,8 @@ import org.apache.ignite.tcbot.common.exeption.ServicesStartingException;
 import org.apache.ignite.tcbot.persistence.TcBotPersistenceModule;
 import org.apache.ignite.tcignited.TeamcityIgnitedModule;
 import org.apache.ignite.tcbot.common.exeption.ExceptionUtil;
-import org.apache.ignite.ci.web.TcUpdatePool;
+import org.apache.ignite.tcbot.engine.pool.TcUpdatePool;
 import org.apache.ignite.ci.web.model.hist.VisasHistoryStorage;
-import org.apache.ignite.ci.web.rest.exception.ServiceStartingExceptionMapper;
 import org.apache.ignite.tcbot.common.interceptor.AutoProfiling;
 import org.apache.ignite.tcbot.common.interceptor.MonitoredTask;
 
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/JiraTicketSync.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/JiraTicketSync.java
index 0813879..6664e87 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/JiraTicketSync.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/jira/ignited/JiraTicketSync.java
@@ -37,7 +37,7 @@ import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.apache.ignite.ci.util.UrlUtil.escape;
+import static org.apache.ignite.tcbot.common.util.UrlUtil.escape;
 
 /**
  * Sync serving requests for all JIRA servers.
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotBusinessServicesModule.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotBusinessServicesModule.java
index aaedf62..2134a3f 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotBusinessServicesModule.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotBusinessServicesModule.java
@@ -19,7 +19,7 @@ package org.apache.ignite.ci.tcbot;
 import com.google.inject.AbstractModule;
 import com.google.inject.internal.SingletonScope;
 import org.apache.ignite.ci.issue.IssuesStorage;
-import org.apache.ignite.ci.tcbot.chain.BuildChainProcessor;
+import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
 import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
 import org.apache.ignite.ci.tcbot.conf.LocalFilesBasedConfig;
 import org.apache.ignite.ci.tcbot.issue.IIssuesStorage;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/builds/CompareBuildsService.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/builds/CompareBuildsService.java
index 2fe7752..05d1e71 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/builds/CompareBuildsService.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/builds/CompareBuildsService.java
@@ -21,7 +21,7 @@ import java.util.ArrayList;
 import java.util.List;
 import javax.inject.Inject;
 import org.apache.ignite.tcbot.engine.chain.MultBuildRunCtx;
-import org.apache.ignite.ci.tcbot.chain.BuildChainProcessor;
+import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
 import org.apache.ignite.tcignited.ITeamcityIgnitedProvider;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java
index 369fb2b..a141286 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java
@@ -22,20 +22,20 @@ import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 import javax.inject.Inject;
-import org.apache.ignite.tcbot.engine.chain.FullChainRunCtx;
-import org.apache.ignite.tcbot.engine.chain.TestCompactedMult;
-import org.apache.ignite.tcbot.engine.chain.LatestRebuildMode;
-import org.apache.ignite.tcbot.engine.chain.ProcessLogsMode;
+
+import org.apache.ignite.ci.github.PullRequest;
+import org.apache.ignite.ci.github.pure.IGitHubConnection;
+import org.apache.ignite.tcbot.engine.chain.*;
 import org.apache.ignite.ci.github.ignited.IGitHubConnIgnited;
 import org.apache.ignite.ci.github.ignited.IGitHubConnIgnitedProvider;
 import org.apache.ignite.ci.jira.ignited.IJiraIgnited;
 import org.apache.ignite.ci.jira.ignited.IJiraIgnitedProvider;
 import org.apache.ignite.ci.tcbot.visa.BranchTicketMatcher;
 import org.apache.ignite.ci.user.ITcBotUserCreds;
-import org.apache.ignite.ci.web.model.current.ChainAtServerCurrentStatus;
-import org.apache.ignite.ci.web.model.current.SuiteCurrentStatus;
-import org.apache.ignite.ci.web.model.current.TestFailure;
-import org.apache.ignite.ci.web.model.current.TestFailuresSummary;
+import org.apache.ignite.tcbot.engine.ui.DsChainUi;
+import org.apache.ignite.tcbot.engine.ui.DsSuiteUi;
+import org.apache.ignite.tcbot.engine.ui.DsTestFailureUi;
+import org.apache.ignite.tcbot.engine.ui.DsSummaryUi;
 import org.apache.ignite.ci.web.rest.parms.FullQueryParams;
 import org.apache.ignite.tcbot.common.interceptor.AutoProfiling;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
@@ -80,7 +80,7 @@ public class PrChainsProcessor {
      * @return Test failures summary.
      */
     @AutoProfiling
-    public TestFailuresSummary getTestFailuresSummary(
+    public DsSummaryUi getTestFailuresSummary(
         ITcBotUserCreds creds,
         String srvCode,
         String suiteId,
@@ -90,7 +90,7 @@ public class PrChainsProcessor {
         @Nullable String baseBranchForTc,
         @Nullable Boolean checkAllLogs,
         SyncMode mode) {
-        final TestFailuresSummary res = new TestFailuresSummary();
+        final DsSummaryUi res = new DsSummaryUi();
         final AtomicInteger runningUpdates = new AtomicInteger();
 
         //using here non persistent TC allows to skip update statistic
@@ -100,7 +100,7 @@ public class PrChainsProcessor {
 
         IJiraIgnited jiraIntegration = jiraIgnProv.server(srvCode);
 
-        res.setJavaFlags(gitHubConnIgnited, jiraIntegration);
+        res.setJavaFlags(gitHubConnIgnited.config(), jiraIntegration.config());
 
         LatestRebuildMode rebuild;
         if (FullQueryParams.HISTORY.equals(act))
@@ -137,7 +137,7 @@ public class PrChainsProcessor {
             baseBranch,
             mode);
 
-        ChainAtServerCurrentStatus chainStatus = new ChainAtServerCurrentStatus(srvCode, tcIgnited.serverCode(), branchForTc);
+        DsChainUi chainStatus = new DsChainUi(srvCode, tcIgnited.serverCode(), branchForTc);
 
         chainStatus.baseBranchForTc = baseBranch;
 
@@ -152,7 +152,7 @@ public class PrChainsProcessor {
             //fail rate reference is always default (master)
             chainStatus.initFromContext(tcIgnited, ctx, baseBranch, compactor, false); // don't need for PR
 
-            chainStatus.initJiraAndGitInfo(ticketMatcher, jiraIntegration, gitHubConnIgnited);
+            initJiraAndGitInfo(chainStatus, jiraIntegration, gitHubConnIgnited);
         }
 
         res.addChainOnServer(chainStatus);
@@ -163,22 +163,62 @@ public class PrChainsProcessor {
     }
 
     /**
+     * Set up ticket and PR related information.
+     *  @param chainStatus Ticket matcher.
+     * @param jiraIntegration Jira integration.
+     * @param gitHubConnIgnited Git hub connection ignited.
+     */
+    public void initJiraAndGitInfo(DsChainUi chainStatus,
+                                   IJiraIgnited jiraIntegration,
+                                   IGitHubConnIgnited gitHubConnIgnited) {
+
+        String ticketFullName = null;
+        String branchName = chainStatus.branchName;
+        try {
+            ticketFullName = ticketMatcher
+                    .resolveTicketFromBranch(jiraIntegration.config().getCode(),
+                            null,
+                            branchName);
+        }
+        catch (BranchTicketMatcher.TicketNotFoundException ignore) {
+        }
+
+        Integer prNum = IGitHubConnection.convertBranchToPrId(branchName);
+
+        String prUrl = null;
+        String ticketUrl = null;
+
+        if (prNum != null) {
+            PullRequest pullReq = gitHubConnIgnited.getPullRequest(prNum);
+
+            if (pullReq != null && pullReq.getTitle() != null)
+                prUrl = pullReq.htmlUrl();
+        }
+
+        if (!Strings.isNullOrEmpty(ticketFullName) && jiraIntegration.config().getUrl() != null)
+            ticketUrl = jiraIntegration.generateTicketUrl(ticketFullName);
+
+        chainStatus.setPrInfo(prNum, prUrl);
+        chainStatus.setJiraTicketInfo(ticketFullName, ticketUrl);
+    }
+
+    /**
      * @param buildTypeId  Build type ID, for which visa was ordered.
      * @param branchForTc Branch for TeamCity.
      * @param srvId Server id.
      * @param prov Credentials.
      * @return List of suites with possible blockers.
      */
-    @Nullable public List<SuiteCurrentStatus> getBlockersSuitesStatuses(String buildTypeId,
-        String branchForTc,
-        String srvId,
-        ITcBotUserCreds prov) {
+    @Nullable public List<DsSuiteUi> getBlockersSuitesStatuses(String buildTypeId,
+                                                               String branchForTc,
+                                                               String srvId,
+                                                               ITcBotUserCreds prov) {
         return getBlockersSuitesStatuses(buildTypeId, branchForTc, srvId, prov, SyncMode.RELOAD_QUEUED);
     }
 
     @Nullable
-    public List<SuiteCurrentStatus> getBlockersSuitesStatuses(String buildTypeId, String branchForTc, String srvId,
-                                                              ITcBotUserCreds prov, SyncMode syncMode) {
+    public List<DsSuiteUi> getBlockersSuitesStatuses(String buildTypeId, String branchForTc, String srvId,
+                                                     ITcBotUserCreds prov, SyncMode syncMode) {
         //using here non persistent TC allows to skip update statistic
         ITeamcityIgnited tcIgnited = tcIgnitedProvider.server(srvId, prov);
 
@@ -208,8 +248,8 @@ public class PrChainsProcessor {
      * @param baseBranch
      */
     //todo may avoid creation of UI model for simple comment.
-    private List<SuiteCurrentStatus> findBlockerFailures(FullChainRunCtx fullChainRunCtx, ITeamcityIgnited tcIgnited,
-        String baseBranch) {
+    private List<DsSuiteUi> findBlockerFailures(FullChainRunCtx fullChainRunCtx, ITeamcityIgnited tcIgnited,
+                                                String baseBranch) {
         return fullChainRunCtx
             .failedChildSuites()
             .map((ctx) -> {
@@ -218,13 +258,13 @@ public class PrChainsProcessor {
 
                 String suiteComment = ctx.getPossibleBlockerComment(compactor, statInBaseBranch, tcIgnited.config());
 
-                List<TestFailure> failures = ctx.getFailedTests().stream().map(occurrence -> {
+                List<DsTestFailureUi> failures = ctx.getFailedTests().stream().map(occurrence -> {
                     IRunHistory stat = tcIgnited.getTestRunHist(occurrence.getName(), normalizedBaseBranch);
 
                     String testBlockerComment = TestCompactedMult.getPossibleBlockerComment(stat);
 
                     if (!Strings.isNullOrEmpty(testBlockerComment)) {
-                        final TestFailure failure = new TestFailure();
+                        final DsTestFailureUi failure = new DsTestFailureUi();
 
                         failure.initFromOccurrence(occurrence, tcIgnited, ctx.projectId(), ctx.branchName(), baseBranch);
 
@@ -237,7 +277,7 @@ public class PrChainsProcessor {
                 // test failure based blockers and/or blocker found by suite results
                 if (!failures.isEmpty() || !Strings.isNullOrEmpty(suiteComment)) {
 
-                    SuiteCurrentStatus suiteUi = new SuiteCurrentStatus();
+                    DsSuiteUi suiteUi = new DsSuiteUi();
                     suiteUi.testFailures = failures;
 
                     suiteUi.initFromContext(tcIgnited, ctx, baseBranch, compactor, false, false);
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java
index b74487d..e3800a7 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java
@@ -23,17 +23,19 @@ import org.apache.ignite.ci.issue.*;
 import org.apache.ignite.ci.jobs.CheckQueueJob;
 import org.apache.ignite.ci.mail.EmailSender;
 import org.apache.ignite.ci.mail.SlackSender;
-import org.apache.ignite.ci.tcbot.chain.TrackedBranchChainsProcessor;
+import org.apache.ignite.tcbot.engine.issue.EventTemplate;
+import org.apache.ignite.tcbot.engine.issue.EventTemplates;
+import org.apache.ignite.tcbot.engine.tracked.TrackedBranchChainsProcessor;
 import org.apache.ignite.ci.tcbot.user.IUserStorage;
 import org.apache.ignite.ci.teamcity.ignited.change.ChangeCompacted;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
 import org.apache.ignite.ci.teamcity.ignited.runhist.InvocationData;
 import org.apache.ignite.ci.user.ITcBotUserCreds;
 import org.apache.ignite.ci.user.TcHelperUser;
-import org.apache.ignite.ci.web.model.current.ChainAtServerCurrentStatus;
-import org.apache.ignite.ci.web.model.current.SuiteCurrentStatus;
-import org.apache.ignite.ci.web.model.current.TestFailure;
-import org.apache.ignite.ci.web.model.current.TestFailuresSummary;
+import org.apache.ignite.tcbot.engine.ui.DsChainUi;
+import org.apache.ignite.tcbot.engine.ui.DsSuiteUi;
+import org.apache.ignite.tcbot.engine.ui.DsTestFailureUi;
+import org.apache.ignite.tcbot.engine.ui.DsSummaryUi;
 import org.apache.ignite.tcbot.common.interceptor.AutoProfiling;
 import org.apache.ignite.tcbot.common.interceptor.MonitoredTask;
 import org.apache.ignite.tcbot.engine.conf.INotificationChannel;
@@ -96,8 +98,8 @@ public class IssueDetector {
     /** Send notification guard. */
     private final AtomicBoolean sndNotificationGuard = new AtomicBoolean();
 
-    private String registerIssuesAndNotifyLater(TestFailuresSummary res,
-        ITcBotUserCreds creds) {
+    private String registerIssuesAndNotifyLater(DsSummaryUi res,
+                                                ITcBotUserCreds creds) {
 
         if (creds == null)
             return null;
@@ -243,10 +245,10 @@ public class IssueDetector {
     @SuppressWarnings({"WeakerAccess", "UnusedReturnValue"})
     @AutoProfiling
     @MonitoredTask(name = "Register new issues")
-    protected String registerNewIssues(TestFailuresSummary res, ITcBotUserCreds creds) {
+    protected String registerNewIssues(DsSummaryUi res, ITcBotUserCreds creds) {
         int newIssues = 0;
 
-        for (ChainAtServerCurrentStatus next : res.servers) {
+        for (DsChainUi next : res.servers) {
             String srvCode = next.serverCode;
 
             if (!tcProv.hasAccess(srvCode, creds))
@@ -254,12 +256,12 @@ public class IssueDetector {
 
             ITeamcityIgnited tcIgnited = tcProv.server(srvCode, creds);
 
-            for (SuiteCurrentStatus suiteCurrentStatus : next.suites) {
+            for (DsSuiteUi suiteCurrentStatus : next.suites) {
                 String normalizeBranch = normalizeBranch(suiteCurrentStatus.branchName());
 
                 final String trackedBranch = res.getTrackedBranch();
 
-                for (TestFailure testFailure : suiteCurrentStatus.testFailures) {
+                for (DsTestFailureUi testFailure : suiteCurrentStatus.testFailures) {
                     if (registerTestFailIssues(tcIgnited, srvCode, normalizeBranch, testFailure, trackedBranch,
                         suiteCurrentStatus.tags))
                         newIssues++;
@@ -285,7 +287,7 @@ public class IssueDetector {
     private boolean registerSuiteFailIssues(ITeamcityIgnited tcIgnited,
         String srvCode,
         String normalizeBranch,
-        SuiteCurrentStatus suiteFailure,
+        DsSuiteUi suiteFailure,
         String trackedBranch) {
 
         String suiteId = suiteFailure.suiteId;
@@ -330,8 +332,8 @@ public class IssueDetector {
     }
 
     @NotNull
-    private Issue createIssueForSuite(ITeamcityIgnited tcIgnited, SuiteCurrentStatus suiteFailure, String trackedBranch,
-        IssueKey issueKey, IssueType issType) {
+    private Issue createIssueForSuite(ITeamcityIgnited tcIgnited, DsSuiteUi suiteFailure, String trackedBranch,
+                                      IssueKey issueKey, IssueType issType) {
         Issue issue = new Issue(issueKey, issType);
         issue.trackedBranchName = trackedBranch;
         issue.displayName = suiteFailure.name;
@@ -360,7 +362,7 @@ public class IssueDetector {
     private boolean registerTestFailIssues(ITeamcityIgnited tcIgnited,
         String srvCode,
         String normalizeBranch,
-        TestFailure testFailure,
+        DsTestFailureUi testFailure,
         String trackedBranch,
         @Nonnull Set<String> suiteTags) {
         String name = testFailure.name;
@@ -493,7 +495,7 @@ public class IssueDetector {
             SyncMode.RELOAD_QUEUED,
             false);
 
-        TestFailuresSummary failures =
+        DsSummaryUi failures =
             tbProc.getTrackedBranchTestFailures(brachName,
                 false,
                 1,
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/trends/MasterTrendsService.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/trends/MasterTrendsService.java
index dfc4f5f..047ceb0 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/trends/MasterTrendsService.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/trends/MasterTrendsService.java
@@ -41,7 +41,7 @@ import javax.inject.Inject;
 import javax.inject.Provider;
 import org.apache.ignite.tcbot.common.interceptor.AutoProfiling;
 import org.apache.ignite.tcbot.common.interceptor.GuavaCached;
-import org.apache.ignite.ci.tcbot.chain.BuildChainProcessor;
+import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
 import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
 import org.apache.ignite.tcservice.model.hist.BuildRef;
 import org.apache.ignite.tcservice.model.result.tests.TestOccurrence;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java
index a742f7d..cd17eaa 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java
@@ -70,9 +70,9 @@ import org.apache.ignite.ci.web.model.JiraCommentResponse;
 import org.apache.ignite.ci.web.model.SimpleResult;
 import org.apache.ignite.ci.web.model.Visa;
 import org.apache.ignite.ci.web.model.VisaRequest;
-import org.apache.ignite.ci.web.model.current.SuiteCurrentStatus;
-import org.apache.ignite.ci.web.model.current.TestFailure;
-import org.apache.ignite.ci.web.model.hist.FailureSummary;
+import org.apache.ignite.tcbot.engine.ui.DsSuiteUi;
+import org.apache.ignite.tcbot.engine.ui.DsTestFailureUi;
+import org.apache.ignite.tcbot.engine.ui.DsHistoryStatUi;
 import org.apache.ignite.ci.web.model.hist.VisasHistoryStorage;
 import org.apache.ignite.internal.util.typedef.F;
 import org.jetbrains.annotations.NotNull;
@@ -722,13 +722,13 @@ public class TcBotTriggerAndSignOffService {
                                                String tcBranch) {
         CurrentVisaStatus status = new CurrentVisaStatus();
 
-        List<SuiteCurrentStatus> suitesStatuses
+        List<DsSuiteUi> suitesStatuses
             = prChainsProcessor.getBlockersSuitesStatuses(buildTypeId, tcBranch, srvCode, prov, SyncMode.NONE);
 
         if (suitesStatuses == null)
             return status;
 
-        status.blockers = suitesStatuses.stream().mapToInt(SuiteCurrentStatus::totalBlockers).sum();
+        status.blockers = suitesStatuses.stream().mapToInt(DsSuiteUi::totalBlockers).sum();
 
         return status;
     }
@@ -772,7 +772,7 @@ public class TcBotTriggerAndSignOffService {
         JiraCommentResponse res;
 
         try {
-            List<SuiteCurrentStatus> suitesStatuses = prChainsProcessor.getBlockersSuitesStatuses(buildTypeId, build.branchName, srvId, prov);
+            List<DsSuiteUi> suitesStatuses = prChainsProcessor.getBlockersSuitesStatuses(buildTypeId, build.branchName, srvId, prov);
 
             if (suitesStatuses == null)
                 return new Visa("JIRA wasn't commented - no finished builds to analyze.");
@@ -809,15 +809,15 @@ public class TcBotTriggerAndSignOffService {
      * @param tcIgnited TC service.
      * @return Comment, which should be sent to the JIRA ticket.
      */
-    private String generateJiraComment(List<SuiteCurrentStatus> suites, String webUrl, String buildTypeId,
-        ITeamcityIgnited tcIgnited) {
+    private String generateJiraComment(List<DsSuiteUi> suites, String webUrl, String buildTypeId,
+                                       ITeamcityIgnited tcIgnited) {
         BuildTypeRefCompacted bt = tcIgnited.getBuildTypeRef(buildTypeId);
 
         String suiteNameUsedForVisa = (bt != null ? bt.name(compactor) : buildTypeId);
 
         StringBuilder res = new StringBuilder();
 
-        for (SuiteCurrentStatus suite : suites) {
+        for (DsSuiteUi suite : suites) {
             res.append("{color:#d04437}").append(jiraEscText(suite.name)).append("{color}");
             res.append(" [[tests ").append(suite.failedTests);
 
@@ -826,7 +826,7 @@ public class TcBotTriggerAndSignOffService {
 
             res.append('|').append(suite.webToBuild).append("]]\\n");
 
-            for (TestFailure failure : suite.testFailures) {
+            for (DsTestFailureUi failure : suite.testFailures) {
                 res.append("* ");
 
                 if (failure.suiteName != null && failure.testName != null)
@@ -834,7 +834,7 @@ public class TcBotTriggerAndSignOffService {
                 else
                     res.append(jiraEscText(failure.name));
 
-                FailureSummary recent = failure.histBaseBranch.recent;
+                DsHistoryStatUi recent = failure.histBaseBranch.recent;
 
                 if (recent != null) {
                     if (recent.failureRate != null) {
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java
index 81d5e59..e637738 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/CtxListener.java
@@ -28,6 +28,7 @@ import javax.servlet.ServletContextListener;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.ci.db.TcHelperDb;
 import org.apache.ignite.ci.di.IgniteTcBotModule;
+import org.apache.ignite.tcbot.engine.pool.TcUpdatePool;
 import org.apache.ignite.tcbot.persistence.scheduler.IScheduler;
 import org.apache.ignite.ci.observer.BuildObserver;
 import org.apache.ignite.ci.tcbot.issue.IssueDetector;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetBuildLog.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetBuildLog.java
index 6c9b640..0952416 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetBuildLog.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetBuildLog.java
@@ -19,6 +19,7 @@ package org.apache.ignite.ci.web.rest;
 
 import com.google.inject.Injector;
 import org.apache.ignite.ci.web.CtxListener;
+import org.apache.ignite.tcbot.engine.ui.BotUrls;
 import org.apache.ignite.tcignited.buildlog.IBuildLogProcessor;
 
 import javax.annotation.security.PermitAll;
@@ -39,14 +40,9 @@ import java.io.Writer;
 /**
  * Build log download, now provides thread dumps
  */
-@Path(GetBuildLog.GET_BUILD_LOG)
+@Path(BotUrls.GetBuildLog.GET_BUILD_LOG)
 @Produces(MediaType.TEXT_PLAIN)
 public class GetBuildLog {
-    public static final String GET_BUILD_LOG = "getBuildLog";
-    public static final String THREAD_DUMP = "threadDump";
-    public static final String SERVER_ID = "serverId";
-    public static final String BUILD_NO = "buildNo";
-    public static final String FILE_IDX = "fileIdx";
 
     /** Servlet Context. */
     @Context
@@ -57,11 +53,11 @@ public class GetBuildLog {
     private HttpServletRequest req;
 
     @GET
-    @Path(THREAD_DUMP)
+    @Path(BotUrls.GetBuildLog.THREAD_DUMP)
     @PermitAll
     public Response getThreadDump(
-        @QueryParam(SERVER_ID) String srvCode,
-        @QueryParam(BUILD_NO) Integer buildId) {
+        @QueryParam(BotUrls.GetBuildLog.SERVER_ID) String srvCode,
+        @QueryParam(BotUrls.GetBuildLog.BUILD_NO) Integer buildId) {
         Injector injector = CtxListener.getInjector(ctx);
 
         IBuildLogProcessor instance = injector.getInstance(IBuildLogProcessor.class);
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java
index 727d793..f8eccb7 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java
@@ -29,7 +29,7 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 
 import com.google.inject.Injector;
-import org.apache.ignite.ci.tcbot.chain.BuildChainProcessor;
+import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
 import org.apache.ignite.tcservice.ITeamcity;
 import org.apache.ignite.tcbot.engine.chain.FullChainRunCtx;
 import org.apache.ignite.tcbot.engine.chain.LatestRebuildMode;
@@ -41,10 +41,10 @@ import org.apache.ignite.tcignited.SyncMode;
 import org.apache.ignite.ci.user.ITcBotUserCreds;
 import org.apache.ignite.tcbot.common.util.FutureUtil;
 import org.apache.ignite.ci.web.CtxListener;
-import org.apache.ignite.ci.web.model.current.ChainAtServerCurrentStatus;
-import org.apache.ignite.ci.web.model.current.SuiteCurrentStatus;
-import org.apache.ignite.ci.web.model.current.TestFailure;
-import org.apache.ignite.ci.web.model.hist.TestHistory;
+import org.apache.ignite.tcbot.engine.ui.DsChainUi;
+import org.apache.ignite.tcbot.engine.ui.DsSuiteUi;
+import org.apache.ignite.tcbot.engine.ui.DsTestFailureUi;
+import org.apache.ignite.tcbot.engine.ui.DsTestHistoryUi;
 
 import static java.lang.Float.parseFloat;
 import static javax.ws.rs.core.MediaType.TEXT_HTML;
@@ -83,7 +83,7 @@ public class GetChainResultsAsHtml {
             failRateBranch,
             SyncMode.RELOAD_QUEUED);
 
-        ChainAtServerCurrentStatus status = new ChainAtServerCurrentStatus(srvCode, tcIgn.serverCode(), ctx.branchName());
+        DsChainUi status = new DsChainUi(srvCode, tcIgn.serverCode(), ctx.branchName());
 
         ctx.getRunningUpdates().forEach(FutureUtil::getResultSilent);
 
@@ -143,7 +143,7 @@ public class GetChainResultsAsHtml {
         return failures!=null;
     }
 
-    private String showChainAtServerData(ChainAtServerCurrentStatus server) {
+    private String showChainAtServerData(DsChainUi server) {
         String res = "";
         String altTxt = "";
 
@@ -164,7 +164,7 @@ public class GetChainResultsAsHtml {
         res += "</b><br><br>";
 
         StringBuilder resBuilder = new StringBuilder(res);
-        for (SuiteCurrentStatus suite : server.suites) {
+        for (DsSuiteUi suite : server.suites) {
             resBuilder.append(showSuiteData(suite));
         }
         res = resBuilder.toString();
@@ -172,7 +172,7 @@ public class GetChainResultsAsHtml {
         return res;
     }
 
-    private String showSuiteData(SuiteCurrentStatus suite) {
+    private String showSuiteData(DsSuiteUi suite) {
         String res = "";
         String altTxt = "duration: " + suite.durationPrintable;
         res += "&nbsp; ";
@@ -208,9 +208,9 @@ public class GetChainResultsAsHtml {
         */
         res+=" <br>";
 
-        List<TestFailure> failures = suite.testFailures;
+        List<DsTestFailureUi> failures = suite.testFailures;
         StringBuilder resBuilder = new StringBuilder(res);
-        for (TestFailure next : failures)
+        for (DsTestFailureUi next : failures)
             resBuilder.append(showTestFailData(next));
         res = resBuilder.toString();
         
@@ -230,7 +230,7 @@ public class GetChainResultsAsHtml {
     }
 
 
-    private String showTestFailData(TestFailure testFail) {
+    private String showTestFailData(DsTestFailureUi testFail) {
         String res = "";
         res += "&nbsp; &nbsp; ";
 
@@ -261,7 +261,7 @@ public class GetChainResultsAsHtml {
         boolean haveWeb = isDefinedAndFilled(testFail.webUrl);
         String histContent = "";
 
-        TestHistory hist;
+        DsTestHistoryUi hist;
 
         if(isDefinedAndFilled(testFail.histBaseBranch))
             hist = testFail.histBaseBranch;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java
index c88cc31..6dd733e 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java
@@ -33,15 +33,15 @@ import javax.ws.rs.core.MediaType;
 import org.apache.ignite.tcbot.engine.chain.FullChainRunCtx;
 import org.apache.ignite.tcbot.engine.chain.LatestRebuildMode;
 import org.apache.ignite.tcbot.engine.chain.ProcessLogsMode;
-import org.apache.ignite.ci.tcbot.chain.BuildChainProcessor;
+import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
 import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
 import org.apache.ignite.ci.tcbot.trends.MasterTrendsService;
 import org.apache.ignite.ci.teamcity.ignited.buildcondition.BuildCondition;
 import org.apache.ignite.ci.user.ITcBotUserCreds;
 import org.apache.ignite.ci.web.CtxListener;
-import org.apache.ignite.ci.web.model.current.ChainAtServerCurrentStatus;
-import org.apache.ignite.ci.web.model.current.TestFailuresSummary;
-import org.apache.ignite.ci.web.model.current.UpdateInfo;
+import org.apache.ignite.tcbot.engine.ui.DsChainUi;
+import org.apache.ignite.tcbot.engine.ui.DsSummaryUi;
+import org.apache.ignite.tcbot.engine.ui.UpdateInfo;
 import org.apache.ignite.ci.web.model.trends.BuildStatisticsSummary;
 import org.apache.ignite.ci.web.model.trends.BuildsHistory;
 import org.apache.ignite.tcbot.common.exeption.ServiceUnauthorizedException;
@@ -89,7 +89,7 @@ public class GetBuildTestFailures {
 
     @GET
     @Path("failuresNoSync")
-    public TestFailuresSummary getBuildTestFailsNoSync(
+    public DsSummaryUi getBuildTestFailsNoSync(
         @QueryParam("serverId") String srvId,
         @QueryParam("buildId") Integer buildId,
         @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs) {
@@ -98,22 +98,22 @@ public class GetBuildTestFailures {
 
     @GET
     @Path("failures")
-    @NotNull public TestFailuresSummary getBuildTestFails(
+    @NotNull public DsSummaryUi getBuildTestFails(
         @QueryParam("serverId") String srvId,
         @QueryParam("buildId") Integer buildId,
         @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs) {
         return collectBuildCtxById(srvId, buildId, checkAllLogs, SyncMode.RELOAD_QUEUED);
     }
 
-    @NotNull public TestFailuresSummary collectBuildCtxById(@QueryParam("serverId") String srvCode,
-        @QueryParam("buildId") Integer buildId,
-        @QueryParam("checkAllLogs") @Nullable Boolean checkAllLogs, SyncMode syncMode) {
+    @NotNull public DsSummaryUi collectBuildCtxById(@QueryParam("serverId") String srvCode,
+                                                    @QueryParam("buildId") Integer buildId,
+                                                    @QueryParam("checkAllLogs") @Nullable Boolean checkAllLogs, SyncMode syncMode) {
         final ITcBotUserCreds prov = ITcBotUserCreds.get(req);
         final Injector injector = CtxListener.getInjector(ctx);
         ITeamcityIgnitedProvider tcIgnitedProv = injector.getInstance(ITeamcityIgnitedProvider.class);
         final BuildChainProcessor buildChainProcessor = injector.getInstance(BuildChainProcessor.class);
 
-        final TestFailuresSummary res = new TestFailuresSummary();
+        final DsSummaryUi res = new DsSummaryUi();
         final AtomicInteger runningUpdates = new AtomicInteger();
 
         tcIgnitedProv.checkAccess(srvCode, prov);
@@ -133,7 +133,7 @@ public class GetBuildTestFailures {
             failRateBranch,
             syncMode);
 
-        ChainAtServerCurrentStatus chainStatus = new ChainAtServerCurrentStatus(srvCode, tcIgnited.serverCode(), ctx.branchName());
+        DsChainUi chainStatus = new DsChainUi(srvCode, tcIgnited.serverCode(), ctx.branchName());
 
         int cnt = (int)ctx.getRunningUpdates().count();
         if (cnt > 0)
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/issues/TcIssues.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/issues/TcIssues.java
index 7753881..f62d867 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/issues/TcIssues.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/issues/TcIssues.java
@@ -31,7 +31,7 @@ import org.apache.ignite.ci.issue.IssueList;
 import org.apache.ignite.ci.tcbot.issue.IIssuesStorage;
 import org.apache.ignite.ci.web.CtxListener;
 import org.apache.ignite.ci.web.model.SimpleResult;
-import org.apache.ignite.ci.web.model.current.UpdateInfo;
+import org.apache.ignite.tcbot.engine.ui.UpdateInfo;
 import org.jetbrains.annotations.Nullable;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/long_running/BuildsLongRunningTestsReport.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/long_running/BuildsLongRunningTestsReport.java
index 34f04af..2eac776 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/long_running/BuildsLongRunningTestsReport.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/long_running/BuildsLongRunningTestsReport.java
@@ -24,10 +24,10 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
-import org.apache.ignite.ci.tcbot.chain.TrackedBranchChainsProcessor;
+import org.apache.ignite.tcbot.engine.tracked.TrackedBranchChainsProcessor;
 import org.apache.ignite.ci.user.ITcBotUserCreds;
 import org.apache.ignite.ci.web.CtxListener;
-import org.apache.ignite.ci.web.model.long_running.FullLRTestsSummary;
+import org.apache.ignite.tcbot.engine.ui.LrTestsFullSummaryUi;
 import org.jetbrains.annotations.Nullable;
 
 @Path(BuildsLongRunningTestsReport.LONG_RUNNING_SUMMARY)
@@ -46,7 +46,7 @@ public class BuildsLongRunningTestsReport {
     @GET
     @Path("summary")
     @Produces(MediaType.APPLICATION_JSON)
-    public FullLRTestsSummary getBranch(@Nullable @QueryParam("branch") String branchOrNull) {
+    public LrTestsFullSummaryUi getBranch(@Nullable @QueryParam("branch") String branchOrNull) {
         final ITcBotUserCreds creds = ITcBotUserCreds.get(req);
 
         final TrackedBranchChainsProcessor tbProc = CtxListener.getInjector(ctx).getInstance(TrackedBranchChainsProcessor.class);
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/pr/GetPrTestFailures.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/pr/GetPrTestFailures.java
index 52454d4..700b3f2 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/pr/GetPrTestFailures.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/pr/GetPrTestFailures.java
@@ -37,8 +37,8 @@ import org.apache.ignite.ci.tcbot.chain.PrChainsProcessor;
 import org.apache.ignite.tcignited.SyncMode;
 import org.apache.ignite.ci.user.ITcBotUserCreds;
 import org.apache.ignite.ci.web.CtxListener;
-import org.apache.ignite.ci.web.model.current.TestFailuresSummary;
-import org.apache.ignite.ci.web.model.current.UpdateInfo;
+import org.apache.ignite.tcbot.engine.ui.DsSummaryUi;
+import org.apache.ignite.tcbot.engine.ui.UpdateInfo;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -71,7 +71,7 @@ public class GetPrTestFailures {
 
     @GET
     @Path("resultsNoSync")
-    public TestFailuresSummary getPrFailuresResultsNoSync(
+    public DsSummaryUi getPrFailuresResultsNoSync(
         @Nullable @QueryParam("serverId") String srvId,
         @Nonnull @QueryParam("suiteId") String suiteId,
         @Nonnull @QueryParam("branchForTc") String branchForTc,
@@ -83,7 +83,7 @@ public class GetPrTestFailures {
         return getPrFailsWithSyncMode(srvId, suiteId, branchForTc, act, cnt, baseBranchForTc, checkAllLogs, SyncMode.NONE);
     }
 
-    public TestFailuresSummary getPrFailsWithSyncMode(
+    public DsSummaryUi getPrFailsWithSyncMode(
         @QueryParam("serverId") @Nullable String srvId,
         @QueryParam("suiteId") @Nonnull String suiteId,
         @QueryParam("branchForTc") @Nonnull String branchForTc,
@@ -111,7 +111,7 @@ public class GetPrTestFailures {
      */
     @GET
     @Path("results")
-    @NotNull public TestFailuresSummary getPrFailures (
+    @NotNull public DsSummaryUi getPrFailures (
         @Nullable @QueryParam("serverId") String srvId,
         @Nonnull @QueryParam("suiteId") String suiteId,
         @Nonnull @QueryParam("branchForTc") String branchForTc,
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java
index a02a798..5d8cce1 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java
@@ -27,13 +27,13 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
-import org.apache.ignite.ci.tcbot.chain.TrackedBranchChainsProcessor;
+import org.apache.ignite.tcbot.engine.tracked.TrackedBranchChainsProcessor;
 import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
 import org.apache.ignite.ci.tcbot.visa.TcBotTriggerAndSignOffService;
 import org.apache.ignite.ci.user.ITcBotUserCreds;
 import org.apache.ignite.ci.web.CtxListener;
-import org.apache.ignite.ci.web.model.current.TestFailuresSummary;
-import org.apache.ignite.ci.web.model.current.UpdateInfo;
+import org.apache.ignite.tcbot.engine.ui.DsSummaryUi;
+import org.apache.ignite.tcbot.engine.ui.UpdateInfo;
 import org.apache.ignite.ci.web.rest.parms.FullQueryParams;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.tcignited.ITeamcityIgnitedProvider;
@@ -76,7 +76,7 @@ public class GetTrackedBranchTestResults {
 
     @GET
     @Path("resultsNoSync")
-    public TestFailuresSummary getTestFailsResultsNoSync(
+    public DsSummaryUi getTestFailsResultsNoSync(
         @Nullable @QueryParam("branch") String branch,
         @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs,
         @QueryParam("trustedTests") @Nullable Boolean trustedTests) {
@@ -86,14 +86,14 @@ public class GetTrackedBranchTestResults {
     @GET
     @Path("results")
     @NotNull
-    public TestFailuresSummary getTestFailsNoCache(
+    public DsSummaryUi getTestFailsNoCache(
         @Nullable @QueryParam("branch") String branch,
         @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs,
         @QueryParam("trustedTests") @Nullable Boolean trustedTests) {
         return latestBuildResults(branch, checkAllLogs, trustedTests, SyncMode.RELOAD_QUEUED);
     }
 
-    @NotNull public TestFailuresSummary latestBuildResults(
+    @NotNull public DsSummaryUi latestBuildResults(
         @QueryParam("branch") @Nullable String branch,
         @QueryParam("checkAllLogs") @Nullable Boolean checkAllLogs,
         @QueryParam("trustedTests") @Nullable Boolean trustedTests,
@@ -117,22 +117,22 @@ public class GetTrackedBranchTestResults {
 
     @GET
     @Path("mergedResultsNoSync")
-    public TestFailuresSummary getAllTestFailsNoSync(@Nullable @QueryParam("branch") String branch,
-        @Nullable @QueryParam("count") Integer cnt,
-        @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs) {
+    public DsSummaryUi getAllTestFailsNoSync(@Nullable @QueryParam("branch") String branch,
+                                             @Nullable @QueryParam("count") Integer cnt,
+                                             @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs) {
         return mergedBuildsResults(branch, cnt, checkAllLogs, SyncMode.NONE);
     }
 
     @GET
     @Path("mergedResults")
     @NotNull
-    public TestFailuresSummary getAllTestFailsForMergedBuidls(@Nullable @QueryParam("branch") String branchOpt,
-        @QueryParam("count") Integer cnt,
-        @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs) {
+    public DsSummaryUi getAllTestFailsForMergedBuidls(@Nullable @QueryParam("branch") String branchOpt,
+                                                      @QueryParam("count") Integer cnt,
+                                                      @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs) {
         return mergedBuildsResults(branchOpt, cnt, checkAllLogs, SyncMode.RELOAD_QUEUED);
     }
 
-    @NotNull public TestFailuresSummary mergedBuildsResults(
+    @NotNull public DsSummaryUi mergedBuildsResults(
         @QueryParam("branch") @Nullable String branchOpt,
         @QueryParam("count") Integer cnt,
         @QueryParam("checkAllLogs") @Nullable Boolean checkAllLogs,
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/di/DiContextTest.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/di/DiContextTest.java
index 12c6e04..01a7b88 100644
--- a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/di/DiContextTest.java
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/di/DiContextTest.java
@@ -26,9 +26,9 @@ import org.apache.ignite.IgniteCache;
 import org.apache.ignite.ci.observer.BuildObserver;
 import org.apache.ignite.ci.observer.ObserverTask;
 import org.apache.ignite.ci.tcbot.ITcBotBgAuth;
-import org.apache.ignite.ci.tcbot.chain.BuildChainProcessor;
+import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
 import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
-import org.apache.ignite.ci.web.TcUpdatePool;
+import org.apache.ignite.tcbot.engine.pool.TcUpdatePool;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.tcbot.common.interceptor.MonitoredTask;
 import org.apache.ignite.tcignited.ITeamcityIgnitedProvider;
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessorTest.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessorTest.java
index 72ca8f6..e8b213f 100644
--- a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessorTest.java
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessorTest.java
@@ -26,13 +26,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import org.apache.ignite.tcbot.engine.chain.*;
 import org.apache.ignite.tcignited.buildlog.IBuildLogProcessor;
 import org.apache.ignite.tcservice.ITeamcity;
-import org.apache.ignite.tcbot.engine.chain.FullChainRunCtx;
-import org.apache.ignite.tcbot.engine.chain.IMultTestOccurrence;
-import org.apache.ignite.tcbot.engine.chain.MultBuildRunCtx;
-import org.apache.ignite.tcbot.engine.chain.LatestRebuildMode;
-import org.apache.ignite.tcbot.engine.chain.ProcessLogsMode;
 import org.apache.ignite.tcservice.model.hist.BuildRef;
 import org.apache.ignite.tcservice.model.result.tests.TestOccurrence;
 import org.apache.ignite.tcservice.model.result.tests.TestOccurrenceFull;
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessorTest.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessorTest.java
index 22a9d9b..2dec781 100644
--- a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessorTest.java
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessorTest.java
@@ -41,8 +41,8 @@ import org.apache.ignite.ci.teamcity.ignited.TeamcityIgnitedProviderMock;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
 import org.apache.ignite.ci.teamcity.ignited.runhist.InvocationData;
 import org.apache.ignite.ci.user.ITcBotUserCreds;
-import org.apache.ignite.ci.web.model.current.SuiteCurrentStatus;
-import org.apache.ignite.ci.web.model.current.TestFailure;
+import org.apache.ignite.tcbot.engine.ui.DsSuiteUi;
+import org.apache.ignite.tcbot.engine.ui.DsTestFailureUi;
 import org.jetbrains.annotations.NotNull;
 import org.junit.Before;
 import org.junit.Test;
@@ -114,7 +114,7 @@ public class PrChainsProcessorTest {
         initBuildChainAndMasterHistory(c, btId, branch);
 
         PrChainsProcessor prcp = injector.getInstance(PrChainsProcessor.class);
-        final List<SuiteCurrentStatus> blockers = prcp.getBlockersSuitesStatuses(btId,
+        final List<DsSuiteUi> blockers = prcp.getBlockersSuitesStatuses(btId,
             branch, SRV_ID, mock(ITcBotUserCreds.class));
 
         System.out.println(blockers);
@@ -131,7 +131,7 @@ public class PrChainsProcessorTest {
         assertFalse(containsTestFailure(blockers, TEST_WITH_HISTORY_FAILING_IN_MASTER));
         assertFalse(containsTestFailure(blockers, TEST_FLAKY_IN_MASTER));
 
-        Optional<TestFailure> testOpt = findBlockerTestFailure(blockers, TEST_WITH_HISTORY_PASSING_IN_MASTER);
+        Optional<DsTestFailureUi> testOpt = findBlockerTestFailure(blockers, TEST_WITH_HISTORY_PASSING_IN_MASTER);
         assertTrue(testOpt.isPresent());
 
         assertTrue(containsTestFailure(blockers, TEST_WAS_FIXED_IN_MASTER));
@@ -141,7 +141,7 @@ public class PrChainsProcessorTest {
         assertTrue(containsTestFailure(blockers, TEST_WITH_HISTORY_PASSING_IN_MASTER));
     }
 
-    public boolean containsTestFailure(List<SuiteCurrentStatus> blockers, String name) {
+    public boolean containsTestFailure(List<DsSuiteUi> blockers, String name) {
         return blockers.stream().anyMatch(containsTestFail(name));
     }
 
@@ -161,12 +161,12 @@ public class PrChainsProcessorTest {
         initHistory(c);
 
         PrChainsProcessor prcp = injector.getInstance(PrChainsProcessor.class);
-        final List<SuiteCurrentStatus> blockers = prcp.getBlockersSuitesStatuses(btId,
+        final List<DsSuiteUi> blockers = prcp.getBlockersSuitesStatuses(btId,
             branch, SRV_ID, mock(ITcBotUserCreds.class));
 
         System.out.println(blockers);
 
-        Optional<TestFailure> rareNotFlaky = findBlockerTestFailure(blockers, TEST_RARE_FAILED_WITH_CHANGES);
+        Optional<DsTestFailureUi> rareNotFlaky = findBlockerTestFailure(blockers, TEST_RARE_FAILED_WITH_CHANGES);
         assertTrue(rareNotFlaky.isPresent());
 
         assertNull(rareNotFlaky.get().histBaseBranch.flakyComments);
@@ -174,8 +174,8 @@ public class PrChainsProcessorTest {
         assertFalse(findBlockerTestFailure(blockers, TEST_RARE_FAILED_WITHOUT_CHANGES).isPresent());
     }
 
-    public Optional<TestFailure> findBlockerTestFailure(List<SuiteCurrentStatus> blockers, String name) {
-        Optional<SuiteCurrentStatus> suiteOpt = blockers.stream().filter(containsTestFail(name)).findAny();
+    public Optional<DsTestFailureUi> findBlockerTestFailure(List<DsSuiteUi> blockers, String name) {
+        Optional<DsSuiteUi> suiteOpt = blockers.stream().filter(containsTestFail(name)).findAny();
 
         return suiteOpt.flatMap(suite -> suite.testFailures.stream().filter(tf -> name.equals(tf.name)).findAny());
     }
@@ -184,7 +184,7 @@ public class PrChainsProcessorTest {
      * @param name Test failure Name to find.
      */
     @NotNull
-    private Predicate<SuiteCurrentStatus> containsTestFail(String name) {
+    private Predicate<DsSuiteUi> containsTestFail(String name) {
         return s -> s.testFailures.stream().anyMatch(testFailure -> {
             return name.equals(testFailure.name);
         });
@@ -439,11 +439,11 @@ public class PrChainsProcessorTest {
 
         PrChainsProcessor prcp = injector.getInstance(PrChainsProcessor.class);
 
-        final List<SuiteCurrentStatus> blockers = prcp.getBlockersSuitesStatuses(btId, branch, SRV_ID, mock(ITcBotUserCreds.class));
+        final List<DsSuiteUi> blockers = prcp.getBlockersSuitesStatuses(btId, branch, SRV_ID, mock(ITcBotUserCreds.class));
 
         System.out.println(blockers);
 
-        Optional<TestFailure> testBecameFailed = findBlockerTestFailure(blockers, TEST_BECAME_FAILED_IN_BRANCH);
+        Optional<DsTestFailureUi> testBecameFailed = findBlockerTestFailure(blockers, TEST_BECAME_FAILED_IN_BRANCH);
         assertTrue(testBecameFailed.isPresent());
     }
 }
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchProcessorTest.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchProcessorTest.java
index a1a21fa..30420bf 100644
--- a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchProcessorTest.java
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchProcessorTest.java
@@ -25,6 +25,8 @@ import com.google.inject.Injector;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.ignite.tcbot.engine.tracked.TrackedBranchChainsProcessor;
 import org.apache.ignite.tcservice.ITeamcity;
 import org.apache.ignite.ci.tcbot.conf.BranchTracked;
 import org.apache.ignite.ci.tcbot.conf.ChainAtServerTracked;
@@ -35,10 +37,10 @@ import org.apache.ignite.tcignited.SyncMode;
 import org.apache.ignite.ci.teamcity.ignited.TeamcityIgnitedProviderMock;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
 import org.apache.ignite.ci.user.ITcBotUserCreds;
-import org.apache.ignite.ci.web.model.current.ChainAtServerCurrentStatus;
-import org.apache.ignite.ci.web.model.current.SuiteCurrentStatus;
-import org.apache.ignite.ci.web.model.current.TestFailure;
-import org.apache.ignite.ci.web.model.current.TestFailuresSummary;
+import org.apache.ignite.tcbot.engine.ui.DsChainUi;
+import org.apache.ignite.tcbot.engine.ui.DsSuiteUi;
+import org.apache.ignite.tcbot.engine.ui.DsTestFailureUi;
+import org.apache.ignite.tcbot.engine.ui.DsSummaryUi;
 import org.jetbrains.annotations.NotNull;
 import org.junit.Before;
 import org.junit.Test;
@@ -114,7 +116,7 @@ public class TrackedBranchProcessorTest {
 
         ITcBotUserCreds mock = mock(ITcBotUserCreds.class);
         when(mock.hasAccess(anyString())).thenReturn(true);
-        TestFailuresSummary failures = tbProc.getTrackedBranchTestFailures(BRACH_NAME,
+        DsSummaryUi failures = tbProc.getTrackedBranchTestFailures(BRACH_NAME,
             false,
             1,
             mock, SyncMode.RELOAD_QUEUED,
@@ -125,37 +127,37 @@ public class TrackedBranchProcessorTest {
 
         assertFalse(failures.servers.isEmpty());
 
-        ChainAtServerCurrentStatus apacheSrv = failures.servers.get(0);
+        DsChainUi apacheSrv = failures.servers.get(0);
 
         assertTrue(apacheSrv.failedTests > 0);
 
         assertFalse(apacheSrv.suites.isEmpty());
 
-        Optional<SuiteCurrentStatus> cache9 = findSuite(apacheSrv, CACHE_9);
+        Optional<DsSuiteUi> cache9 = findSuite(apacheSrv, CACHE_9);
         assertTrue(cache9.isPresent());
 
-        SuiteCurrentStatus suiteFails = cache9.get();
+        DsSuiteUi suiteFails = cache9.get();
         assertFalse(suiteFails.testFailures.isEmpty());
 
-        Optional<TestFailure> tfOpt = findTestFailure(suiteFails, TEST_RARE_FAILED_WITH_CHANGES);
+        Optional<DsTestFailureUi> tfOpt = findTestFailure(suiteFails, TEST_RARE_FAILED_WITH_CHANGES);
         assertTrue(tfOpt.isPresent());
         assertNull(tfOpt.get().histBaseBranch.flakyComments);
         assertNull(tfOpt.get().problemRef);
 
-        Optional<TestFailure> tfFlakyOpt = findTestFailure(suiteFails, TEST_RARE_FAILED_WITHOUT_CHANGES);
+        Optional<DsTestFailureUi> tfFlakyOpt = findTestFailure(suiteFails, TEST_RARE_FAILED_WITHOUT_CHANGES);
         assertTrue(tfFlakyOpt.isPresent());
         assertNotNull(tfFlakyOpt.get().histBaseBranch.flakyComments);
 
         assertNull(tfFlakyOpt.get().problemRef);
     }
 
-    public Optional<SuiteCurrentStatus> findSuite(ChainAtServerCurrentStatus apacheSrv, String suiteName) {
+    public Optional<DsSuiteUi> findSuite(DsChainUi apacheSrv, String suiteName) {
         return apacheSrv.suites.stream().filter(s -> {
             return s.name.contains(suiteName);
         }).findAny();
     }
 
-    public Optional<TestFailure> findTestFailure(SuiteCurrentStatus suiteFails, String name) {
+    public Optional<DsTestFailureUi> findTestFailure(DsSuiteUi suiteFails, String name) {
         return suiteFails.testFailures.stream().filter(tf -> tf.name.equals(name)).findAny();
     }
 
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/UrlUtil.java b/tcbot-common/src/main/java/org/apache/ignite/tcbot/common/util/UrlUtil.java
similarity index 96%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/UrlUtil.java
rename to tcbot-common/src/main/java/org/apache/ignite/tcbot/common/util/UrlUtil.java
index f33472c..3252bb5 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/util/UrlUtil.java
+++ b/tcbot-common/src/main/java/org/apache/ignite/tcbot/common/util/UrlUtil.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.util;
+package org.apache.ignite.tcbot.common.util;
 
 import com.google.common.base.Strings;
 import java.io.UnsupportedEncodingException;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessor.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/BuildChainProcessor.java
similarity index 93%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessor.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/BuildChainProcessor.java
index 2f69f69..62bb209 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessor.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/BuildChainProcessor.java
@@ -15,23 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.tcbot.chain;
+package org.apache.ignite.tcbot.engine.chain;
 
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.Futures;
-import org.apache.ignite.tcbot.engine.chain.FullChainRunCtx;
-import org.apache.ignite.tcbot.engine.chain.MultBuildRunCtx;
-import org.apache.ignite.tcbot.engine.chain.SingleBuildRunCtx;
-import org.apache.ignite.tcbot.engine.chain.LatestRebuildMode;
-import org.apache.ignite.tcbot.engine.chain.ProcessLogsMode;
 import org.apache.ignite.ci.teamcity.ignited.BuildRefCompacted;
 import org.apache.ignite.ci.teamcity.ignited.buildtype.ParametersCompacted;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
 import org.apache.ignite.tcbot.common.util.FutureUtil;
-import org.apache.ignite.ci.web.TcUpdatePool;
-import org.apache.ignite.ci.web.model.long_running.LRTest;
-import org.apache.ignite.ci.web.model.long_running.SuiteLRTestsSummary;
+import org.apache.ignite.tcbot.engine.pool.TcUpdatePool;
 import org.apache.ignite.tcbot.common.interceptor.AutoProfiling;
+import org.apache.ignite.tcbot.engine.ui.LrTestUi;
+import org.apache.ignite.tcbot.engine.ui.LrTestsSuiteSummaryUi;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
 import org.apache.ignite.tcignited.SyncMode;
@@ -40,12 +35,11 @@ import org.apache.ignite.tcignited.history.IRunHistory;
 import org.apache.ignite.tcignited.history.RunHistSync;
 import org.apache.ignite.tcservice.model.hist.BuildRef;
 import org.apache.ignite.tcservice.model.result.Build;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import javax.inject.Inject;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
@@ -77,11 +71,11 @@ public class BuildChainProcessor {
      * @param entryPoints
      * @return list of summaries about individual suite runs.
      */
-    public List<SuiteLRTestsSummary> loadLongRunningTestsSummary(
+    public List<LrTestsSuiteSummaryUi> loadLongRunningTestsSummary(
         ITeamcityIgnited teamcityIgnited,
         Collection<Integer> entryPoints
     ) {
-        final List<SuiteLRTestsSummary> res = new ArrayList<>();
+        final List<LrTestsSuiteSummaryUi> res = new ArrayList<>();
 
         SyncMode mode = SyncMode.RELOAD_QUEUED;
 
@@ -94,7 +88,7 @@ public class BuildChainProcessor {
             .filter(b -> !b.isComposite() && b.getTestsCount() > 0)
             .forEach(b ->
             {
-                List<LRTest> lrTests = new ArrayList<>();
+                List<LrTestUi> lrTests = new ArrayList<>();
 
                 b.getAllTests()
                     .filter(t -> {
@@ -104,7 +98,7 @@ public class BuildChainProcessor {
                     })
                     .forEach(
                         t -> lrTests
-                            .add(new LRTest(t.testName(compactor), t.getDuration(), null))
+                            .add(new LrTestUi(t.testName(compactor), t.getDuration(), null))
                     );
 
                 if (!lrTests.isEmpty()) {
@@ -117,7 +111,7 @@ public class BuildChainProcessor {
                     });
 
                     res.add(
-                        new SuiteLRTestsSummary(b.buildTypeName(compactor),
+                        new LrTestsSuiteSummaryUi(b.buildTypeName(compactor),
                             b.buildDuration(compactor) / b.getTestsCount(),
                             lrTests));
                 }
@@ -213,7 +207,7 @@ public class BuildChainProcessor {
         return fullChainRunCtx;
     }
 
-    @NotNull
+    @Nonnull
     public Map<Integer, Future<FatBuildCompacted>> loadAllBuildsInChains(Collection<Integer> entryPoints,
         SyncMode mode,
         ITeamcityIgnited tcIgn) {
@@ -244,7 +238,7 @@ public class BuildChainProcessor {
         return builds;
     }
 
-    @NotNull
+    @Nonnull
     public Map<String, List<FatBuildCompacted>> groupByBuildType(Map<Integer, Future<FatBuildCompacted>> builds) {
         Map<String, List<FatBuildCompacted>> buildsByBt = new ConcurrentHashMap<>();
         builds.values().forEach(bFut -> {
@@ -285,7 +279,7 @@ public class BuildChainProcessor {
     }
 
     @SuppressWarnings("WeakerAccess")
-    @NotNull
+    @Nonnull
     @AutoProfiling
     protected List<Future<FatBuildCompacted>> replaceWithRecent(List<FatBuildCompacted> builds,
         int cntLimit,
@@ -380,7 +374,7 @@ public class BuildChainProcessor {
      * @param teamcityIgnited Teamcity ignited.
      * @return Set of new builds found during this dependencies check round.
      */
-    @NotNull
+    @Nonnull
     private Set<Integer> dependencies(
         Future<FatBuildCompacted> buildFut,
         SyncMode mode,
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/EventTemplate.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplate.java
similarity index 97%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/EventTemplate.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplate.java
index 3bd7a8e..9aad878 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/EventTemplate.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplate.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.issue;
+package org.apache.ignite.tcbot.engine.issue;
 
 import org.apache.ignite.tcignited.history.IEventTemplate;
 
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/EventTemplates.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplates.java
similarity index 98%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/EventTemplates.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplates.java
index d824ef1..5bd11b8 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/EventTemplates.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplates.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.issue;
+package org.apache.ignite.tcbot.engine.issue;
 
 import com.google.common.collect.Lists;
 import java.util.ArrayList;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/TcUpdatePool.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/pool/TcUpdatePool.java
similarity index 97%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/TcUpdatePool.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/pool/TcUpdatePool.java
index 3c1b2dd..e6461c9 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/TcUpdatePool.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/pool/TcUpdatePool.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.web;
+package org.apache.ignite.tcbot.engine.pool;
 
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchChainsProcessor.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/TrackedBranchChainsProcessor.java
similarity index 86%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchChainsProcessor.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/TrackedBranchChainsProcessor.java
index c46b097..bda0b02 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchChainsProcessor.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/TrackedBranchChainsProcessor.java
@@ -14,30 +14,31 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.ci.tcbot.chain;
+package org.apache.ignite.tcbot.engine.tracked;
 
 import java.util.Comparator;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import javax.inject.Inject;
 
 import org.apache.ignite.tcbot.common.conf.ITcServerConfig;
+import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
 import org.apache.ignite.tcbot.engine.chain.FullChainRunCtx;
 import org.apache.ignite.tcbot.engine.chain.LatestRebuildMode;
 import org.apache.ignite.tcbot.engine.chain.ProcessLogsMode;
 import org.apache.ignite.tcbot.common.interceptor.AutoProfiling;
 import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
 import org.apache.ignite.tcbot.engine.conf.ITrackedBranch;
+import org.apache.ignite.tcbot.engine.ui.DsChainUi;
+import org.apache.ignite.tcbot.engine.ui.LrTestsFullSummaryUi;
+import org.apache.ignite.tcbot.engine.ui.DsSummaryUi;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
 import org.apache.ignite.tcignited.ITeamcityIgnitedProvider;
 import org.apache.ignite.tcignited.SyncMode;
-import org.apache.ignite.ci.user.ITcBotUserCreds;
-import org.apache.ignite.ci.web.model.current.ChainAtServerCurrentStatus;
-import org.apache.ignite.ci.web.model.current.TestFailuresSummary;
-import org.apache.ignite.ci.web.model.long_running.FullLRTestsSummary;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import org.apache.ignite.tcignited.creds.ICredentialsProv;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
 
@@ -57,15 +58,15 @@ public class TrackedBranchChainsProcessor {
     @Inject private IStringCompactor compactor;
 
     @AutoProfiling
-    @NotNull
-    public TestFailuresSummary getTrackedBranchTestFailures(
+    @Nonnull
+    public DsSummaryUi getTrackedBranchTestFailures(
         @Nullable String branch,
         @Nullable Boolean checkAllLogs,
         int buildResMergeCnt,
-        ITcBotUserCreds creds,
+        ICredentialsProv creds,
         SyncMode syncMode,
         boolean calcTrustedTests) {
-        final TestFailuresSummary res = new TestFailuresSummary();
+        final DsSummaryUi res = new DsSummaryUi();
         final AtomicInteger runningUpdates = new AtomicInteger();
 
         final String branchNn = isNullOrEmpty(branch) ? ITcServerConfig.DEFAULT_TRACKED_BRANCH_NAME : branch;
@@ -85,7 +86,7 @@ public class TrackedBranchChainsProcessor {
 
                 ITeamcityIgnited tcIgnited = tcIgnitedProv.server(srvCode, creds);
 
-                ChainAtServerCurrentStatus chainStatus = new ChainAtServerCurrentStatus(srvCode,
+                DsChainUi chainStatus = new DsChainUi(srvCode,
                     tcIgnited.serverCode(),
                     branchForTc);
 
@@ -125,7 +126,7 @@ public class TrackedBranchChainsProcessor {
             })
             .forEach(res::addChainOnServer);
 
-        res.servers.sort(Comparator.comparing(ChainAtServerCurrentStatus::serverName));
+        res.servers.sort(Comparator.comparing(DsChainUi::serverName));
 
         res.postProcess(runningUpdates.get());
 
@@ -139,9 +140,9 @@ public class TrackedBranchChainsProcessor {
      * @param creds
      * @return
      */
-    public FullLRTestsSummary getTrackedBranchLongRunningTestsSummary(@Nullable String branch,
-        ITcBotUserCreds creds) {
-        FullLRTestsSummary summary = new FullLRTestsSummary();
+    public LrTestsFullSummaryUi getTrackedBranchLongRunningTestsSummary(@Nullable String branch,
+                                                                        ICredentialsProv creds) {
+        LrTestsFullSummaryUi summary = new LrTestsFullSummaryUi();
 
         final String branchNn = isNullOrEmpty(branch) ? ITcServerConfig.DEFAULT_TRACKED_BRANCH_NAME : branch;
         final ITrackedBranch tracked = tcBotCfg.getTrackedBranches().getBranchMandatory(branchNn);
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/FullLRTestsSummary.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BotUrls.java
similarity index 67%
copy from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/FullLRTestsSummary.java
copy to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BotUrls.java
index b71a77e..bb0f8c8 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/FullLRTestsSummary.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BotUrls.java
@@ -14,19 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.ci.web.model.long_running;
 
-import java.util.ArrayList;
-import java.util.List;
+package org.apache.ignite.tcbot.engine.ui;
 
-/**
- *
- */
-@SuppressWarnings("WeakerAccess")
-public class FullLRTestsSummary {
-    public List<SuiteLRTestsSummary> suiteSummaries = new ArrayList<>();
-
-    public void addSuiteSummaries(List<SuiteLRTestsSummary> summaries) {
-        suiteSummaries.addAll(summaries);
+public class BotUrls {
+    public class GetBuildLog {
+        public static final String FILE_IDX = "fileIdx";
+        public static final String GET_BUILD_LOG = "getBuildLog";
+        public static final String SERVER_ID = "serverId";
+        public static final String BUILD_NO = "buildNo";
+        public static final String THREAD_DUMP = "threadDump";
     }
 }
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/ChainAtServerCurrentStatus.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsChainUi.java
similarity index 80%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/ChainAtServerCurrentStatus.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsChainUi.java
index a2763f2..913c08a 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/ChainAtServerCurrentStatus.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsChainUi.java
@@ -15,9 +15,8 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.web.model.current;
+package org.apache.ignite.tcbot.engine.ui;
 
-import com.google.common.base.Strings;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
@@ -25,32 +24,30 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Stream;
 import javax.annotation.Nullable;
+
+import org.apache.ignite.tcbot.common.util.UrlUtil;
 import org.apache.ignite.tcbot.engine.chain.FullChainRunCtx;
 import org.apache.ignite.tcbot.engine.chain.IMultTestOccurrence;
 import org.apache.ignite.tcbot.engine.chain.MultBuildRunCtx;
-import org.apache.ignite.ci.github.PullRequest;
-import org.apache.ignite.ci.github.ignited.IGitHubConnIgnited;
-import org.apache.ignite.ci.github.pure.IGitHubConnection;
-import org.apache.ignite.ci.jira.ignited.IJiraIgnited;
-import org.apache.ignite.ci.tcbot.visa.BranchTicketMatcher;
 import org.apache.ignite.tcbot.common.util.CollectionUtil;
 import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
 import org.apache.ignite.tcservice.model.conf.BuildType;
 
-import static org.apache.ignite.ci.util.UrlUtil.escape;
-import static org.apache.ignite.ci.web.model.current.SuiteCurrentStatus.branchForLink;
-import static org.apache.ignite.ci.web.model.current.SuiteCurrentStatus.createOccurForLogConsumer;
-import static org.apache.ignite.ci.web.model.current.SuiteCurrentStatus.createOrrucForLongRun;
+import static org.apache.ignite.tcbot.engine.ui.DsSuiteUi.branchForLink;
+import static org.apache.ignite.tcbot.engine.ui.DsSuiteUi.createOccurForLogConsumer;
+import static org.apache.ignite.tcbot.engine.ui.DsSuiteUi.createOrrucForLongRun;
 
 /**
+ * Detailed status of PR or tracked branch for chain.
+ *
  * Represent Run All chain results/ or RunAll+latest re-runs.
  *
  * Persisted as part of cached result. Renaming require background updater migration.
  */
 @SuppressWarnings({"WeakerAccess", "PublicField"})
-public class ChainAtServerCurrentStatus {
+public class DsChainUi {
     /** {@link BuildType#getName()} */
     public String chainName;
 
@@ -86,7 +83,7 @@ public class ChainAtServerCurrentStatus {
     public String webToPr;
 
     /** Suites involved in chain. */
-    public List<SuiteCurrentStatus> suites = new ArrayList<>();
+    public List<DsSuiteUi> suites = new ArrayList<>();
 
     /** Count of failed tests not muted tests. In case several runs are used, overall by all runs. */
     public Integer failedTests;
@@ -119,10 +116,10 @@ public class ChainAtServerCurrentStatus {
     public String lostInTimeouts;
 
     /** top long running suites */
-    public List<TestFailure> topLongRunning = new ArrayList<>();
+    public List<DsTestFailureUi> topLongRunning = new ArrayList<>();
 
     /** top log data producing tests . */
-    public List<TestFailure> logConsumers = new ArrayList<>();
+    public List<DsTestFailureUi> logConsumers = new ArrayList<>();
 
     /** Special flag if chain entry point not found */
     public boolean buildNotFound;
@@ -137,7 +134,7 @@ public class ChainAtServerCurrentStatus {
      * @param tcSvcCode Tc service code.
      * @param branchTc Branch tc.
      */
-    public ChainAtServerCurrentStatus(String srvCode, String tcSvcCode, String branchTc) {
+    public DsChainUi(String srvCode, String tcSvcCode, String branchTc) {
         this.serverCode = srvCode;
         this.tcServerCode = tcSvcCode;
         this.serverId = tcSvcCode;
@@ -157,45 +154,7 @@ public class ChainAtServerCurrentStatus {
     }
 
 
-    /**
-     * Set up ticket and PR related information.
-     *
-     * @param ticketMatcher Ticket matcher.
-     * @param jiraIntegration Jira integration.
-     * @param gitHubConnIgnited Git hub connection ignited.
-     */
-    public void initJiraAndGitInfo(BranchTicketMatcher ticketMatcher,
-        IJiraIgnited jiraIntegration,
-        IGitHubConnIgnited gitHubConnIgnited) {
-
-        String ticketFullName = null;
-        try {
-            ticketFullName = ticketMatcher
-                .resolveTicketFromBranch(jiraIntegration.config().getCode(),
-                    null,
-                    branchName);
-        }
-        catch (BranchTicketMatcher.TicketNotFoundException ignore) {
-        }
-
-        Integer prNum = IGitHubConnection.convertBranchToPrId(branchName);
 
-        String prUrl = null;
-        String ticketUrl = null;
-
-        if (prNum != null) {
-            PullRequest pullReq = gitHubConnIgnited.getPullRequest(prNum);
-
-            if (pullReq != null && pullReq.getTitle() != null)
-                prUrl = pullReq.htmlUrl();
-        }
-
-        if (!Strings.isNullOrEmpty(ticketFullName) && jiraIntegration.config().getUrl() != null)
-            ticketUrl = jiraIntegration.generateTicketUrl(ticketFullName);
-
-        setPrInfo(prNum, prUrl);
-        setJiraTicketInfo(ticketFullName, ticketUrl);
-    }
 
     public void initFromContext(ITeamcityIgnited tcIgnited,
         FullChainRunCtx ctx,
@@ -211,7 +170,7 @@ public class ChainAtServerCurrentStatus {
 
         stream.forEach(
             suite -> {
-                final SuiteCurrentStatus suiteCurStatus = new SuiteCurrentStatus();
+                final DsSuiteUi suiteCurStatus = new DsSuiteUi();
 
                 suiteCurStatus.initFromContext(tcIgnited, suite, baseBranchTc, compactor, true, calcTrustedTests);
 
@@ -229,7 +188,7 @@ public class ChainAtServerCurrentStatus {
             //todo odd convertion
             ctx.suites().filter(s -> !s.isFailed()).forEach(suite -> {
 
-                final SuiteCurrentStatus suiteCurStatus = new SuiteCurrentStatus();
+                final DsSuiteUi suiteCurStatus = new DsSuiteUi();
 
                 suiteCurStatus.initFromContext(tcIgnited, suite, baseBranchTc, compactor, true, calcTrustedTests);
 
@@ -238,7 +197,7 @@ public class ChainAtServerCurrentStatus {
             });
         }
 
-        totalBlockers = suites.stream().mapToInt(SuiteCurrentStatus::totalBlockers).sum();
+        totalBlockers = suites.stream().mapToInt(DsSuiteUi::totalBlockers).sum();
         durationPrintable = ctx.getDurationPrintable();
         testsDurationPrintable = ctx.getTestsDurationPrintable();
         durationNetTimePrintable = ctx.durationNetTimePrintable();
@@ -260,7 +219,7 @@ public class ChainAtServerCurrentStatus {
                 MultBuildRunCtx suite = pairCtxAndOccur.get1();
                 IMultTestOccurrence longRunningOccur = pairCtxAndOccur.get2();
 
-                TestFailure failure = createOrrucForLongRun(tcIgnited, suite, longRunningOccur, baseBranchTc);
+                DsTestFailureUi failure = createOrrucForLongRun(tcIgnited, suite, longRunningOccur, baseBranchTc);
 
                 failure.testName = "[" + suite.suiteName() + "] " + failure.testName; //may be separate field
 
@@ -279,7 +238,7 @@ public class ChainAtServerCurrentStatus {
                 MultBuildRunCtx suite = pairCtxAndOccur.get1();
                 Map.Entry<String, Long> testLogConsuming = pairCtxAndOccur.get2();
 
-                TestFailure failure = createOccurForLogConsumer(testLogConsuming);
+                DsTestFailureUi failure = createOccurForLogConsumer(testLogConsuming);
 
                 failure.name = "[" + suite.suiteName() + "] " + failure.name; //todo suite as be separate field
 
@@ -295,7 +254,7 @@ public class ChainAtServerCurrentStatus {
     private static String buildWebLink(ITeamcityIgnited teamcity, FullChainRunCtx suite) {
         final String branch = branchForLink(suite.branchName());
         return teamcity.host() + "viewType.html?buildTypeId=" + suite.suiteId()
-            + "&branch=" + escape(branch)
+            + "&branch=" + UrlUtil.escape(branch)
             + "&tab=buildTypeStatusDiv";
     }
 
@@ -312,7 +271,7 @@ public class ChainAtServerCurrentStatus {
             return true;
         if (o == null || getClass() != o.getClass())
             return false;
-        ChainAtServerCurrentStatus status = (ChainAtServerCurrentStatus)o;
+        DsChainUi status = (DsChainUi)o;
         return buildNotFound == status.buildNotFound &&
             Objects.equals(chainName, status.chainName) &&
             Objects.equals(serverId, status.serverId) &&
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/hist/FailureSummary.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsHistoryStatUi.java
similarity index 93%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/hist/FailureSummary.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsHistoryStatUi.java
index 2389215..844f207 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/hist/FailureSummary.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsHistoryStatUi.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.web.model.hist;
+package org.apache.ignite.tcbot.engine.ui;
 
 import java.util.Objects;
 import javax.annotation.Nullable;
@@ -23,7 +23,7 @@ import javax.annotation.Nullable;
 /**
  * Test failure summary: contains statistic of failures and total runs for suite or for test.
  */
-public class FailureSummary {
+public class DsHistoryStatUi {
     /** Registered number of failures from TC helper DB */
     @Nullable public Integer failures;
 
@@ -39,7 +39,7 @@ public class FailureSummary {
             return true;
         if (o == null || getClass() != o.getClass())
             return false;
-        FailureSummary summary = (FailureSummary)o;
+        DsHistoryStatUi summary = (DsHistoryStatUi)o;
 
         return Objects.equals(failures, summary.failures) &&
             Objects.equals(runs, summary.runs) &&
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/ProblemRef.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsProblemRef.java
similarity index 90%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/ProblemRef.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsProblemRef.java
index 7c04fbd..f20dd72 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/ProblemRef.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsProblemRef.java
@@ -15,17 +15,17 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.issue;
+package org.apache.ignite.tcbot.engine.ui;
 
 /**
  * Reference to some Issue with current suite or test detected by the Bot.
  * Currently contains only display name.
  */
-public class ProblemRef {
+public class DsProblemRef {
     public String name;
     public String webUrl;
 
-    public ProblemRef(String name) {
+    public DsProblemRef(String name) {
         this.name = name;
     }
 }
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/SuiteCurrentStatus.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsSuiteUi.java
similarity index 85%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/SuiteCurrentStatus.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsSuiteUi.java
index b03e2a2..8d25cf2 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/SuiteCurrentStatus.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsSuiteUi.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.web.model.current;
+package org.apache.ignite.tcbot.engine.ui;
 
 import com.google.common.base.Strings;
 import java.util.ArrayList;
@@ -29,26 +29,28 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+
+import org.apache.ignite.tcbot.common.util.UrlUtil;
 import org.apache.ignite.tcbot.engine.chain.IMultTestOccurrence;
 import org.apache.ignite.tcbot.engine.chain.MultBuildRunCtx;
-import org.apache.ignite.ci.issue.EventTemplates;
-import org.apache.ignite.ci.issue.ProblemRef;
+import org.apache.ignite.tcbot.engine.issue.EventTemplates;
+import org.apache.ignite.tcbot.engine.ui.BotUrls.GetBuildLog;
 import org.apache.ignite.tcignited.buildlog.ITestLogCheckResult;
 import org.apache.ignite.tcignited.history.IRunHistory;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
-import org.apache.ignite.ci.web.model.hist.FailureSummary;
-import org.apache.ignite.ci.web.rest.GetBuildLog;
-import org.jetbrains.annotations.NotNull;
 
 import static org.apache.ignite.tcignited.history.RunHistSync.normalizeBranch;
 import static org.apache.ignite.tcbot.common.util.TimeUtil.millisToDurationPrintable;
-import static org.apache.ignite.ci.util.UrlUtil.escape;
+
 
 /**
+ * Detailed status of failures: Suite failures.
+ *
  * Represent Suite result, UI class for REST responses, so it contains public fields
  */
-@SuppressWarnings({"WeakerAccess", "PublicField"}) public class SuiteCurrentStatus extends FailureSummary {
+@SuppressWarnings({"WeakerAccess", "PublicField"})
+public class DsSuiteUi extends DsHistoryStatUi {
     /** Suite Name */
     public String name;
 
@@ -67,10 +69,10 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
     /** Web Href. to suite particular run */
     public String webToBuild = "";
 
-    public List<TestFailure> testFailures = new ArrayList<>();
-    public List<TestFailure> topLongRunning = new ArrayList<>();
-    public List<TestFailure> warnOnly = new ArrayList<>();
-    public List<TestFailure> logConsumers = new ArrayList<>();
+    public List<DsTestFailureUi> testFailures = new ArrayList<>();
+    public List<DsTestFailureUi> topLongRunning = new ArrayList<>();
+    public List<DsTestFailureUi> warnOnly = new ArrayList<>();
+    public List<DsTestFailureUi> logConsumers = new ArrayList<>();
 
     /** Web Href. to thread dump display */
     @Nullable public String webUrlThreadDump;
@@ -89,10 +91,10 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
     public String branchName;
 
     /** Failure summary in tracked branch according to all runs history. */
-    @Nonnull public FailureSummary failsAllHist = new FailureSummary();
+    @Nonnull public DsHistoryStatUi failsAllHist = new DsHistoryStatUi();
 
     /** Failure summary in tracked branch according to all runs history. */
-    @Nonnull public FailureSummary criticalFails = new FailureSummary();
+    @Nonnull public DsHistoryStatUi criticalFails = new DsHistoryStatUi();
 
     /** Latest runs, 0,1,3 values for each run. */
     @Nullable public List<Integer> latestRuns;
@@ -133,7 +135,7 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
     /**
      * Advisory mark there is problem in this suite.
      */
-    @Nullable public ProblemRef problemRef;
+    @Nullable public DsProblemRef problemRef;
 
     /** Tags for build. */
     @Nonnull public Set<String> tags = new HashSet<>();
@@ -152,12 +154,12 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
      * @param includeTests Include tests - usually {@code true}, but it may be disabled for speeding up VISA collection.
      * @param calcTrustedTests
      */
-    public SuiteCurrentStatus initFromContext(ITeamcityIgnited tcIgnited,
-        @Nonnull final MultBuildRunCtx suite,
-        @Nullable final String baseBranch,
-        @Nonnull IStringCompactor compactor,
-        boolean includeTests,
-        boolean calcTrustedTests) {
+    public DsSuiteUi initFromContext(ITeamcityIgnited tcIgnited,
+                                     @Nonnull final MultBuildRunCtx suite,
+                                     @Nullable final String baseBranch,
+                                     @Nonnull IStringCompactor compactor,
+                                     boolean includeTests,
+                                     boolean calcTrustedTests) {
 
         name = suite.suiteName();
 
@@ -195,7 +197,7 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
             tests.sort(Comparator.comparing(function).reversed());
 
             tests.forEach(occurrence -> {
-                final TestFailure failure = new TestFailure();
+                final DsTestFailureUi failure = new DsTestFailureUi();
                 failure.initFromOccurrence(occurrence, tcIgnited, suite.projectId(), suite.branchName(), baseBranch);
                 failure.initStat(tcIgnited, failRateNormalizedBranch, curBranchNormalized);
 
@@ -203,14 +205,14 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
             });
 
             suite.getTopLongRunning().forEach(occurrence -> {
-                final TestFailure failure = createOrrucForLongRun(tcIgnited, suite, occurrence, baseBranch);
+                final DsTestFailureUi failure = createOrrucForLongRun(tcIgnited, suite, occurrence, baseBranch);
 
                 topLongRunning.add(failure);
             });
 
             suite.getCriticalFailLastStartedTest().forEach(
                 lastTest -> {
-                    final TestFailure failure = new TestFailure();
+                    final DsTestFailureUi failure = new DsTestFailureUi();
                     failure.name = lastTest + " (last started)";
                     testFailures.add(failure);
                 }
@@ -295,28 +297,28 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
 
         if (latestRunsSrc != null) {
             if (latestRunsSrc.detectTemplate(EventTemplates.newFailureForFlakyTest) != null)
-                problemRef = new ProblemRef("New Failure");
+                problemRef = new DsProblemRef("New Failure");
 
             if (latestRunsSrc.detectTemplate(EventTemplates.newCriticalFailure) != null)
-                problemRef = new ProblemRef("New Critical Failure");
+                problemRef = new DsProblemRef("New Critical Failure");
         }
 
         return statInBaseBranch;
     }
 
-    @NotNull
-    public static TestFailure createOccurForLogConsumer(Map.Entry<String, Long> entry) {
-        TestFailure failure = new TestFailure();
+    @Nonnull
+    public static DsTestFailureUi createOccurForLogConsumer(Map.Entry<String, Long> entry) {
+        DsTestFailureUi failure = new DsTestFailureUi();
         long sizeMb = entry.getValue() / 1024 / 1024;
         failure.name = entry.getKey() + " " + sizeMb + " Mbytes";
         return failure;
     }
 
-    @NotNull public static TestFailure createOrrucForLongRun(ITeamcityIgnited tcIgnited,
-        @Nonnull MultBuildRunCtx suite,
-        final IMultTestOccurrence occurrence,
-        @Nullable final String failRateBranch) {
-        final TestFailure failure = new TestFailure();
+    @Nonnull public static DsTestFailureUi createOrrucForLongRun(ITeamcityIgnited tcIgnited,
+                                                                 @Nonnull MultBuildRunCtx suite,
+                                                                 final IMultTestOccurrence occurrence,
+                                                                 @Nullable final String failRateBranch) {
+        final DsTestFailureUi failure = new DsTestFailureUi();
 
         failure.initFromOccurrence(occurrence, tcIgnited, suite.projectId(), suite.branchName(), failRateBranch);
 
@@ -328,11 +330,11 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
     }
 
     public void findFailureAndAddWarning(String testName, ITestLogCheckResult logCheckRes) {
-        TestFailure failure = testFailures.stream().filter(f -> f.name.contains(testName)).findAny().orElseGet(
+        DsTestFailureUi failure = testFailures.stream().filter(f -> f.name.contains(testName)).findAny().orElseGet(
             () -> {
                 return warnOnly.stream().filter(f -> f.name.contains(testName)).findAny().orElseGet(
                     () -> {
-                        TestFailure f = new TestFailure();
+                        DsTestFailureUi f = new DsTestFailureUi();
                         f.name = testName + " (warning)";
                         warnOnly.add(f);
 
@@ -353,10 +355,10 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
         return buildWebLink(teamcity, suite, branchName);
     }
 
-    @NotNull private static String buildWebLink(ITeamcityIgnited teamcity, MultBuildRunCtx suite, String branchName) {
+    @Nonnull private static String buildWebLink(ITeamcityIgnited teamcity, MultBuildRunCtx suite, String branchName) {
         final String branch = branchForLink(branchName);
         return teamcity.host() + "viewType.html?buildTypeId=" + suite.suiteId()
-            + "&branch=" + escape(branch)
+            + "&branch=" + UrlUtil.escape(branch)
             + "&tab=buildTypeStatusDiv";
     }
 
@@ -372,7 +374,7 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
             return false;
         if (!super.equals(o))
             return false;
-        SuiteCurrentStatus status = (SuiteCurrentStatus)o;
+        DsSuiteUi status = (DsSuiteUi)o;
         return Objects.equals(name, status.name) &&
             Objects.equals(result, status.result) &&
             Objects.equals(hasCriticalProblem, status.hasCriticalProblem) &&
@@ -438,7 +440,7 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
         if (!Strings.isNullOrEmpty(blockerComment))
             res++;
 
-        res += (int)testFailures.stream().filter(TestFailure::isPossibleBlocker).count();
+        res += (int)testFailures.stream().filter(DsTestFailureUi::isPossibleBlocker).count();
 
         return res;
     }
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailuresSummary.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsSummaryUi.java
similarity index 86%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailuresSummary.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsSummaryUi.java
index 634053b..8c23f54 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailuresSummary.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsSummaryUi.java
@@ -15,20 +15,24 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.web.model.current;
+package org.apache.ignite.tcbot.engine.ui;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.jetbrains.annotations.Nullable;
+
+import javax.annotation.Nullable;
 
 /**
+ * Detailed status model for overall response.
+ *
  * Summary of failures from all servers. UI model, so it contains public fields.
  */
-@SuppressWarnings({"WeakerAccess", "PublicField"}) public class TestFailuresSummary extends UpdateInfo {
+@SuppressWarnings({"WeakerAccess", "PublicField"})
+public class DsSummaryUi extends UpdateInfo {
     /** Servers (Services) and their chain results. */
-    public List<ChainAtServerCurrentStatus> servers = new ArrayList<>();
+    public List<DsChainUi> servers = new ArrayList<>();
 
     public Integer failedTests;
 
@@ -36,9 +40,10 @@ import org.jetbrains.annotations.Nullable;
     public Integer failedToFinish;
 
     /** Tracked branch ID. */
-    @Nullable private String trackedBranch;
+    @Nullable
+    private String trackedBranch;
 
-    public void addChainOnServer(ChainAtServerCurrentStatus chainStatus) {
+    public void addChainOnServer(DsChainUi chainStatus) {
         servers.add(chainStatus);
 
         if (chainStatus.failedToFinish != null) {
@@ -68,7 +73,7 @@ import org.jetbrains.annotations.Nullable;
             return true;
         if (o == null || getClass() != o.getClass())
             return false;
-        TestFailuresSummary summary = (TestFailuresSummary)o;
+        DsSummaryUi summary = (DsSummaryUi)o;
         return Objects.equals(servers, summary.servers) &&
             Objects.equals(failedTests, summary.failedTests) &&
             Objects.equals(failedToFinish, summary.failedToFinish) &&
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailure.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsTestFailureUi.java
similarity index 91%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailure.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsTestFailureUi.java
index 9557cf4..6c86abb 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailure.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsTestFailureUi.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.web.model.current;
+package org.apache.ignite.tcbot.engine.ui;
 
 import com.google.common.base.Strings;
 import java.util.ArrayList;
@@ -25,25 +25,24 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+
+import org.apache.ignite.tcbot.common.util.UrlUtil;
 import org.apache.ignite.tcbot.engine.chain.IMultTestOccurrence;
 import org.apache.ignite.tcbot.engine.chain.TestCompactedMult;
-import org.apache.ignite.ci.issue.EventTemplates;
-import org.apache.ignite.ci.issue.ProblemRef;
+import org.apache.ignite.tcbot.engine.issue.EventTemplates;
 import org.apache.ignite.tcignited.buildlog.LogMsgToWarn;
 import org.apache.ignite.tcignited.history.IRunHistory;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
-import org.apache.ignite.ci.web.model.hist.FailureSummary;
-import org.apache.ignite.ci.web.model.hist.TestHistory;
-import org.jetbrains.annotations.NotNull;
 
 import static org.apache.ignite.tcignited.history.RunHistSync.normalizeBranch;
 import static org.apache.ignite.tcbot.common.util.TimeUtil.millisToDurationPrintable;
-import static org.apache.ignite.ci.util.UrlUtil.escape;
+
 
 /**
  * UI model for test failure, probably merged with its history
  */
-@SuppressWarnings({"WeakerAccess", "PublicField"}) public class TestFailure {
+@SuppressWarnings({"WeakerAccess", "PublicField"})
+public class DsTestFailureUi {
     /** Test full Name */
     public String name;
 
@@ -75,15 +74,15 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
 
     public List<String> warnings = new ArrayList<>();
 
-    @Nullable public ProblemRef problemRef;
+    @Nullable public DsProblemRef problemRef;
 
     /** History cur branch. If it is absent, history is to be taken from histBaseBranch. */
-    @Nullable public TestHistory histCurBranch;
+    @Nullable public DsTestHistoryUi histCurBranch;
 
     /**
      * This history is created only for PR/Branch failures, it contains data from the base branch (e.g. master).
      */
-    @NotNull public TestHistory histBaseBranch = new TestHistory();
+    @Nonnull public DsTestHistoryUi histBaseBranch = new DsTestHistoryUi();
 
     /** Link to test history for current branch. */
     @Nullable public String webUrlBaseBranch;
@@ -187,7 +186,7 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
         return tcIgn.host() + "project.html"
             + "?projectId=" + projectId
             + "&testNameId=" + id
-            + "&branch=" + escape(branch)
+            + "&branch=" + UrlUtil.escape(branch)
             + "&tab=testDetails";
     }
 
@@ -210,7 +209,7 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
             statForProblemsDetection = tcIgnited.getTestRunHist(name, curBranchNormalized);
 
             if (statForProblemsDetection != null) {
-                histCurBranch = new TestHistory();
+                histCurBranch = new DsTestHistoryUi();
 
                 histCurBranch.init(statForProblemsDetection);
             }
@@ -220,10 +219,10 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
 
         if (statForProblemsDetection != null) {
             if (statForProblemsDetection.detectTemplate(EventTemplates.newFailure) != null)
-                problemRef = new ProblemRef("New Failure");
+                problemRef = new DsProblemRef("New Failure");
 
             if (statForProblemsDetection.detectTemplate(EventTemplates.newContributedTestFailure) != null)
-                problemRef = new ProblemRef("Recently contributed test failure");
+                problemRef = new DsProblemRef("Recently contributed test failure");
         }
     }
 
@@ -233,7 +232,7 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
             return true;
         if (o == null || getClass() != o.getClass())
             return false;
-        TestFailure failure = (TestFailure)o;
+        DsTestFailureUi failure = (DsTestFailureUi)o;
         return investigated == failure.investigated &&
             Objects.equals(name, failure.name) &&
             Objects.equals(suiteName, failure.suiteName) &&
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/hist/TestHistory.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsTestHistoryUi.java
similarity index 90%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/hist/TestHistory.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsTestHistoryUi.java
index a6fd120..8b8597f 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/hist/TestHistory.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsTestHistoryUi.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.web.model.hist;
+package org.apache.ignite.tcbot.engine.ui;
 
 import java.util.List;
 import java.util.Objects;
@@ -25,12 +25,12 @@ import org.apache.ignite.tcignited.history.IRunHistory;
 /**
  * Summary of failures - all history and recent runs for suite or for suite.
  */
-public class TestHistory {
+public class DsTestHistoryUi {
     /** 'All the time' runs history statistic. */
-    public FailureSummary allTime = new FailureSummary();
+    public DsHistoryStatUi allTime = new DsHistoryStatUi();
 
     /** Latest runs history statistic. */
-    public FailureSummary recent = new FailureSummary();
+    public DsHistoryStatUi recent = new DsHistoryStatUi();
 
     /** Latest runs, 0,1,2 values for each run. */
     @Nullable public List<Integer> latestRuns;
@@ -61,7 +61,7 @@ public class TestHistory {
             return true;
         if (o == null || getClass() != o.getClass())
             return false;
-        TestHistory hist = (TestHistory)o;
+        DsTestHistoryUi hist = (DsTestHistoryUi)o;
         return Objects.equals(allTime, hist.allTime) &&
             Objects.equals(recent, hist.recent) &&
             Objects.equals(latestRuns, hist.latestRuns) &&
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/LRTest.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/LrTestUi.java
similarity index 87%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/LRTest.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/LrTestUi.java
index 93f5e3b..f975e40 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/LRTest.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/LrTestUi.java
@@ -14,14 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.ci.web.model.long_running;
+package org.apache.ignite.tcbot.engine.ui;
 
 import static org.apache.ignite.tcbot.common.util.TimeUtil.millisToDurationPrintable;
 
 /**
  *
  */
-public class LRTest {
+@SuppressWarnings("WeakerAccess")
+public class LrTestUi {
     public String name;
 
     public long time;
@@ -30,7 +31,7 @@ public class LRTest {
 
     public String webLink;
 
-    public LRTest(String name, long time, String webLink) {
+    public LrTestUi(String name, long time, String webLink) {
         this.name = name;
         this.time = time;
         timePrintable = millisToDurationPrintable(time);
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/FullLRTestsSummary.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/LrTestsFullSummaryUi.java
similarity index 80%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/FullLRTestsSummary.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/LrTestsFullSummaryUi.java
index b71a77e..b0fe77d 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/FullLRTestsSummary.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/LrTestsFullSummaryUi.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.ci.web.model.long_running;
+package org.apache.ignite.tcbot.engine.ui;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -23,10 +23,10 @@ import java.util.List;
  *
  */
 @SuppressWarnings("WeakerAccess")
-public class FullLRTestsSummary {
-    public List<SuiteLRTestsSummary> suiteSummaries = new ArrayList<>();
+public class LrTestsFullSummaryUi {
+    public List<LrTestsSuiteSummaryUi> suiteSummaries = new ArrayList<>();
 
-    public void addSuiteSummaries(List<SuiteLRTestsSummary> summaries) {
+    public void addSuiteSummaries(List<LrTestsSuiteSummaryUi> summaries) {
         suiteSummaries.addAll(summaries);
     }
 }
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/SuiteLRTestsSummary.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/LrTestsSuiteSummaryUi.java
similarity index 85%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/SuiteLRTestsSummary.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/LrTestsSuiteSummaryUi.java
index 683bb02..df1dd80 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/long_running/SuiteLRTestsSummary.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/LrTestsSuiteSummaryUi.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.ci.web.model.long_running;
+package org.apache.ignite.tcbot.engine.ui;
 
 import java.util.List;
 
@@ -24,16 +24,16 @@ import static org.apache.ignite.tcbot.common.util.TimeUtil.millisToDurationPrint
  *
  */
 @SuppressWarnings("WeakerAccess")
-public class SuiteLRTestsSummary {
+public class LrTestsSuiteSummaryUi {
     public String name;
 
     public long testAvgTime;
 
     public String testAvgTimePrintable;
 
-    public List<LRTest> tests;
+    public List<LrTestUi> tests;
 
-    public SuiteLRTestsSummary(String name, long testAvgTime, List<LRTest> tests) {
+    public LrTestsSuiteSummaryUi(String name, long testAvgTime, List<LrTestUi> tests) {
         this.name = name;
         this.testAvgTime = testAvgTime;
         testAvgTimePrintable = millisToDurationPrintable(testAvgTime);
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/README.md b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/README.md
new file mode 100644
index 0000000..fd4ffa1
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/README.md
@@ -0,0 +1,7 @@
+This package contains UI (REST) models for sending to UI.
+
+These classes are not persisted so renaming of classes is ok.
+
+But field names can be used by some JS scripts.
+
+Public fields are used for simplicity and scanning of properties by Jersey.
\ No newline at end of file
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/UpdateInfo.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/UpdateInfo.java
similarity index 79%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/UpdateInfo.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/UpdateInfo.java
index 9830f41..6e31a09 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/UpdateInfo.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/UpdateInfo.java
@@ -15,10 +15,10 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.web.model.current;
+package org.apache.ignite.tcbot.engine.ui;
 
-import org.apache.ignite.ci.github.ignited.IGitHubConnIgnited;
-import org.apache.ignite.ci.jira.ignited.IJiraIgnited;
+import org.apache.ignite.tcbot.common.conf.IGitHubConfig;
+import org.apache.ignite.tcbot.common.conf.IJiraServerConfig;
 
 /**
  * General update information for JS data updating requests. UI model, so it contains public fields.
@@ -51,18 +51,17 @@ import org.apache.ignite.ci.jira.ignited.IJiraIgnited;
     }
 
     /**
-     * @param gitHubConn GitHub integration associated with this server.
-     * @param jiraIntegration JIRA Integration
+     * @param gitHubConfig
+     * @param jiraCfg
      */
-    public void setJavaFlags(IGitHubConnIgnited gitHubConn,
-                             IJiraIgnited jiraIntegration) {
+    public void setJavaFlags(IGitHubConfig gitHubConfig, IJiraServerConfig jiraCfg) {
         //since user has logged in, TC flag should be set
         javaFlags |= TEAMCITY_FLAG;
 
-        if (gitHubConn.config().isGitTokenAvailable())
+        if (gitHubConfig.isGitTokenAvailable())
             javaFlags |= GITHUB_FLAG;
 
-        if (jiraIntegration.config().isJiraTokenAvailable())
+        if (jiraCfg.isJiraTokenAvailable())
             javaFlags |= JIRA_FLAG;
     }
 }